📄 readmib.c
字号:
/* add_node_to_oid_tree attempts to add a node with a specified object identifier, name, and type to the MIB tree referenced by the global mibt. (This tree is in the "nametree" format output by the epilogue MIB compiler -nametree option.) add_node_to_oid_tree assumes that the MIB tree already contains nodes corresponding to all but the final component of the specified object identifier, and that it does not contain a node corresponding to the final component of the specified object identifier. It will write an error to stderr if either assumption proves false. if it is successful, add_node_to_oid_tree returns a pointer to the newly added node; otherwise it returns NULL.*/nametree* add_node_to_oid_tree( char* oid, char* name, char* type ){ char* s; nametree* parent; nametree** sibs; nametree* n; nametree* prev; unsigned long number; parent = 0; sibs = &mibt; s = strtok( oid, "." ); while (s != 0) { number = STRTOUL( s, 0, 10 ); if (s != oid) *(s-1) = '.'; s = strtok( 0, "." ); if (s == 0) { /* terminal component of oid. error if node exists. otherwise, create new node and link into tree. */ for (prev = 0, n = *sibs; n && (n->number < number); prev = n, n = n->sibling) ; if (n && (n->number == number)) { error( "duplicate oid \"%s\"", oid ); return 0; } n = new_node(); n->number = number; n->name = StrDup( name ); n->parent = parent; n->type = convert_type( type ); if (prev == 0) { n->sibling = *sibs; *sibs = n; } else { n->sibling = prev->sibling; prev->sibling = n; } } else { /* nonterminal component of oid. error if node does not exist. */ for (n = *sibs; n && (n->number < number); n = n->sibling) ; if ((n == 0) || (n->number != number)) { if (s != oid) *(s-1) = '.'; error( "the node \"%s\" has undefined ancestors", oid ); return 0; } sibs = &n->children; } parent = n; } return parent;}/* parse_enum is called to continue parsing a line beginning with a $enum directive. It invokes strtok to parse an object identifier, enumerated identifier, and enumerated value from the input line held internally by strtok. parse_enum returns 1 if it successfully parsed these three items; otherwise it returns 0. if parse_enum returns 1, the character string pointers referenced by the char** parameters oid, name, and value have been set to point to null-terminated strings containing the text of the parsed object identifier, enumerated identifier, and enumerated value, respectively. NOTE that parse_enum does no checking of the parsed values to which it returns pointers. A return value of 1 means only three non-empty strings were parsed. NOTE ALSO that the character string pointers returned by parse_enum may reference STATIC memory, depending on the type of argument passed as the first argument to strtok prior to invoking parse_enum.*/int parse_enum( char** oid, char** name, char** value ){ int ok = 0; *oid = *name = *value = 0; *oid = strtok( 0, " \t" ); if (*oid != 0) { *name = strtok( 0, " \t(" ); if (*name != 0) { *value = strtok( 0, " \t)" ); ok = 1; } } return ok;}nametree* add_enum( char* oid, char* name, char* value ){ nametree* n = 0; nametree* node; node = find_node( oid ); if (node == 0) error( "$enum references undefined OBJECT IDENTIFIER \"%s\"", oid ); else if (node->type != VT_NUMBER) error( "only an INTEGER-valued object can have enumerated values" ); else { char* end; unsigned long number = STRTOL( value, &end, 10 ); if (end != (value + STRLEN( value ))) error( "the number \"%s\" is too large or had non-numeric characterss", value ); else { nametree* prev; for (prev = 0, n = node->children; n && (n->number < number); prev = n, n = n->sibling) ; if (n && (n->number == number)) { error( "duplicate named number \"%s\"", value ); return 0; } n = new_node(); n->number = number; n->name = StrDup( name ); n->parent = (prev == 0) ? node : prev; n->type = 0; if (prev == 0) { n->sibling = node->children; node->children = n; } else { n->sibling = prev->sibling; prev->sibling = n; } if (n->sibling != 0) n->sibling->parent = n; } } return n;}/* find_node searches the MIB tree referenced by the global mibt for the node with the specified object identifier. It returns a pointer to the node if it exists, or 0 otherwise.*/nametree* find_node( char* oid ){ char* s; nametree* n; unsigned long number; s = strtok( oid, "." ); if (s == 0) return 0; for (n = mibt; n; n = n->children) { number = STRTOUL( s, 0, 10 ); if (s != oid) *(s-1) = '.'; for ( ; n && (n->number < number); n = n->sibling) ; if ((n == 0) || (n->number != number)) { n = 0; break; } s = strtok( 0, "." ); if (s == 0) break; } return n;}/* new_node returns a pointer to a new MIB tree node dynamically allocated from the free store. The memory is zeroed. NOTE: new_node uses "chunky" allocation, allocating NODE_ALLOC_COUNT MIB tree nodes at a time from the free store and maintaining a linked list of unused nodes for use in satisfying future requests. This may result in up to (NODE_ALLOC_COUNT-1) * sizeof(nametree) unused bytes being unnecessarily allocated from the free store.*/nametree* new_node(){ static nametree* freeNodes = 0; nametree* n; if (freeNodes == 0) { nametree* lastNode; freeNodes = (nametree*)MemAlloc( NODE_ALLOC_COUNT * sizeof(nametree) ); lastNode = freeNodes + (NODE_ALLOC_COUNT - 1); for (n = freeNodes; n != lastNode; n->sibling = n + 1, n = n->sibling) ; n->sibling = 0; } n = freeNodes; freeNodes = n->sibling; MEMSET( n, 0, sizeof(nametree) ); return n;}/* convert_type converts a 0-terminated string containing an "epilogue type" name (of the form VT_xxxx) to the corresponding one-byte ASN.1 tag value.*/int convert_type( char* type ){ if (STRCMP( type, "0" ) == 0) return 0; else if (STRCMP( type, "VT_NUMBER" ) == 0) return VT_NUMBER; /* 0x02 */ else if (STRCMP( type, "VT_COUNTER" ) == 0) return VT_COUNTER; /* 0x41 */ else if (STRCMP( type, "VT_STRING" ) == 0) return VT_STRING; /* 0x04 */ else if (STRCMP( type, "VT_OBJECT" ) == 0) return VT_OBJECT; /* 0x06 */ else if (STRCMP( type, "VT_IPADDRESS" ) == 0) return VT_IPADDRESS; /* 0x40 */ else if (STRCMP( type, "VT_TIMETICKS" ) == 0) return VT_TIMETICKS; /* 0x43 */ else if (STRCMP( type, "VT_GAUGE" ) == 0) return VT_GAUGE; /* 0x42 */ else if (STRCMP( type, "VT_OPAQUE" ) == 0) return VT_OPAQUE; /* 0x44 */ else if (STRCMP( type, "VT_COUNTER64" ) == 0) return VT_COUNTER64; /* 0x46 */ else if (STRCMP( type, "VT_EMPTY" ) == 0) return VT_EMPTY; /* 0x05 */ else return 0;}#if 0 /* this routine doesn't seem to be used so leave it out - dab *//* resolve_type converts a one-byte ASN.1 tag value to a null-terminated string containing the corresponding "epilogue type" name (of the form VT_xxxx).*/static char* resolve_type( int type ){ char* result; switch (type) { case 0: result = "0"; break; case VT_NUMBER: /* 0x02 */ result = "VT_NUMBER"; break; case VT_COUNTER: /* 0x41 */ result = "VT_COUNTER"; break; case VT_STRING: /* 0x04 */ result = "VT_STRING"; break; case VT_OBJECT: /* 0x06 */ result = "VT_OBJECT"; break; case VT_IPADDRESS: /* 0x40 */ result = "VT_IPADDRESS"; break; case VT_TIMETICKS: /* 0x43 */ result = "VT_TIMETICKS"; break; case VT_GAUGE: /* 0x42 */ result = "VT_GAUGE"; break; case VT_OPAQUE: /* 0x44 */ result = "VT_OPAQUE"; break; case VT_COUNTER64: /* 0x46 */ result = "VT_COUNTER64"; break; case VT_EMPTY: /* 0x05 */ result = "VT_EMPTY"; break; default: result = "0"; break; } return result;}#endif /* 0 *//* error writes a file input error message to stderr. error takes a variable number of arguments, the first of which is a printf format string. The error message written to stderr is prefixed by the following: file "<infilename>", line <lineno>, error: where <inputfilename> is replaced by the text of the null-terminated character string referenced by the global infilename, and <n> is replaced by the value of the global lineno.*/#ifdef SUN_VARARGSvoid error( va_alist )va_dcl{ va_list args; char *format; va_start( args ); fprintf( stderr, "file \"%s\", line %d, error: ", infilename, lineno ); format = va_arg( args, char * ); vfprintf( stderr, format, args ); va_end( args ); fprintf( stderr, "\n" );}#else /* SUN_VARARGS */void error( char* format, ... ){ va_list ap; fprintf( stderr, "file \"%s\", line %d, error: ", infilename, lineno ); va_start( ap, format ); vfprintf( stderr, format, ap ); va_end( ap ); fprintf( stderr, "\n" );}#endif /* SUN_VARARGS *//* error2 writes a generic error message to stderr. error2 takes a variable number of arguments, the first of which is a printf format string. The error message written to stderr is prefixed by the following: error: */#ifdef SUN_VARARGSvoid error2( va_alist )va_dcl{ va_list args; char *format; va_start( args ); fprintf( stderr, "error: " ); format = va_arg( args, char * ); vfprintf( stderr, format, args ); va_end( args ); fprintf( stderr, "\n" );}#else /* SUN_VARARGS */void error2( char* format, ... ){ va_list ap; fprintf( stderr, "error: " ); va_start( ap, format ); vfprintf( stderr, format, ap ); va_end( ap ); fprintf( stderr, "\n" );}#endif /* SUN_VARARGS *//* MemAlloc is a "cover" for the standard library function malloc. It is identical in function to malloc, with the exception that if it is unable to fulfill an allocation request, rather than returning 0, it writes an "out of memory" error to stderr and terminates by calling exit.*/void* MemAlloc( size_t size ){ void* p = malloc( size ); if (p == 0) { error( "out of memory" ); exit( 1 ); } return p;}/* MemFree is a cover for the standard library routine free. It is identical in function to free.*/void MemFree( void* p ){ free( p );}/* StrDup reurns a pointer to a dynamically allocated copy of the null-terminated character string referenced by its single parameter <str>.*/char* StrDup( char* str ){ char* s = (char*)MemAlloc( STRLEN( str ) + 1 ); STRCPY( s, str ); return s;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -