|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T o
Length: 12204 (0x2fac) Types: TextFile Names: »objects.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« └─⟦de7628f85⟧ └─⟦this⟧ »isode-6.0/snmp/objects.c«
/* objects.c - SMI object handling */ #ifndef lint static char *rcsid = "$Header: /f/osi/snmp/RCS/objects.c,v 7.1 90/01/11 18:34:23 mrose Exp $"; #endif /* * $Header: /f/osi/snmp/RCS/objects.c,v 7.1 90/01/11 18:34:23 mrose Exp $ * * Contributed by NYSERNet Inc. This work was partially supported by the * U.S. Defense Advanced Research Projects Agency and the Rome Air Development * Center of the U.S. Air Force Systems Command under contract number * F30602-88-C-0016. * * * $Log: objects.c,v $ * Revision 7.1 90/01/11 18:34:23 mrose * real-sync * * Revision 7.0 89/11/23 22:23:18 mrose * Release 6.0 * */ /* * NOTICE * * Acquisition, use, and distribution of this module and related * materials are subject to the restrictions of a license agreement. * Consult the Preface in the User's Manual for the full terms of * this agreement. * */ #include <ctype.h> #include <stdio.h> #include "objects.h" #include "tailor.h" /* \f DATA */ #define TBUCKETS 0x80 static int once_only = 0; static OT Tbuckets[TBUCKETS]; static OT anchor; static OT chain; OID resolve (); extern int errno; /* \f OBJECTS */ static int THASH (name) char *name; { char c; register char *cp, *dp; for (c = *(dp = cp = name); *cp; cp++) if (isupper (*cp)) c = tolower (*(dp = cp)); if (*++dp) return (((c - *dp) & 0x1f) + (*(dp + 1) & 0x5f)); else return (c & 0x7f); } static int ot_compar (a, b) OT *a, *b; { int i = oid_cmp ((*a) -> ot_name, (*b) -> ot_name); if (i == 0) { if (PY_pepy[0]) (void) sprintf (PY_pepy + strlen (PY_pepy), ", "); else (void) sprintf (PY_pepy, "duplicate objects: "); (void) sprintf (PY_pepy + strlen (PY_pepy), "\"%s\" and \"%s\"", (*a) -> ot_text, (*b) -> ot_text); } return i; } int readobjects () { register int j; int again, hit, i; register char *cp; char buffer[BUFSIZ], line[BUFSIZ], *vec[NVEC + NSLACK + 1]; register OT ot, *op, *ep; OT *base, oz; FILE *fp; if (once_only == 0) { bzero ((char *) Tbuckets, sizeof Tbuckets); readsyntax (); if (read_name ("iso", "1") == NOTOK || read_name ("ccitt", "2") == NOTOK || read_name ("joint-iso-ccitt", "3") == NOTOK) return NOTOK; once_only = 1; } if ((fp = fopen ("objects.defs", "r")) == NULL && (fp = fopen (cp = isodefile ("objects.defs", 0), "r")) == NULL) { (void) sprintf (PY_pepy, "unable to read %s: %s", cp, sys_errname (errno)); return NOTOK; } while (fgets (buffer, sizeof buffer, fp)) { if (*buffer == '#' || strncmp (buffer, "--", 2) == 0) continue; if (cp = index (buffer, '\n')) *cp = NULL; (void) strcpy (line, buffer); bzero ((char *) vec, sizeof vec); switch (str2vec (buffer, vec)) { case 0: break; case 2: if (read_name (vec[0], vec[1]) == NOTOK) return NOTOK; break; case 5: if (read_type (vec) == NOTOK) return NOTOK; break; default: (void) sprintf (PY_pepy, "malformed line: \"%s\"", line); return NOTOK; } } (void) fclose (fp); hit = 1, oz = NULLOT; do { if (!hit) { (void) sprintf (PY_pepy, "unable to resolve object \"%s\"", oz -> ot_text); return NOTOK; } again = hit = 0; for (i = 0; i < TBUCKETS; i++) for (ot = Tbuckets[i]; ot && ot -> ot_text; ot = ot -> ot_chain) if (ot -> ot_name == NULLOID) if (ot -> ot_name = resolve (ot -> ot_id, ot)) hit = 1; else oz = ot, again = 1; } while (again); #ifdef notdef for (i = 0; i < TBUCKETS; i++) { hit = 0; for (ot = Tbuckets[i]; ot && ot -> ot_text; ot = ot -> ot_chain) { if (!hit) printf ("Bucket %d:\n", i), hit = 1; printf (" %s %s %s %s %d %d\n", ot -> ot_text, ot -> ot_id, sprintoid (ot -> ot_name), ot -> ot_syntax ? ot -> ot_syntax -> os_name : "NULL", ot -> ot_access, ot -> ot_status); } } #endif j = 0; for (i = 0; i < TBUCKETS; i++) for (ot = Tbuckets[i]; ot && ot -> ot_text; ot = ot -> ot_chain) j++; /* j > 1 ALWAYS */ if ((base = (OT *) malloc ((unsigned) (j * sizeof *base))) == NULL) { (void) sprintf (PY_pepy, "out of memory"); return NOTOK; } op = base; for (i = 0; i < TBUCKETS; i++) for (ot = Tbuckets[i]; ot && ot -> ot_text; ot = ot -> ot_chain) *op++ = ot; ep = op; PY_pepy[0] = NULL; qsort ((char *) base, j, sizeof *base, ot_compar); op = base; anchor = ot = *op++; while (op < ep) { ot -> ot_next = *op; ot = *op++; } (chain = ot) -> ot_next = NULL; free ((char *) base); return (PY_pepy[0] ? NOTOK : OK); } /* \f */ static int read_name (name, value) char *name, *value; { int i; register OT ot; if (text2obj (name)) { (void) sprintf (PY_pepy, "duplicate object \"%s\"", name); return NOTOK; } if ((ot = (OT) calloc (1, sizeof *ot)) == NULL) { (void) sprintf (PY_pepy, "out of memory"); return NOTOK; } if ((ot -> ot_text = strdup (name)) == NULL || (ot -> ot_id = strdup (value)) == NULL) { (void) sprintf (PY_pepy, "out of memory"); return NOTOK; } ot -> ot_chain = Tbuckets[i = THASH (name)]; Tbuckets[i] = ot; return OK; } /* \f */ static int read_type (vec) char **vec; { int i; register OT ot; if (text2obj (*vec)) { (void) sprintf (PY_pepy, "duplicate object \"%s\"", *vec); return NOTOK; } if ((ot = (OT) calloc (1, sizeof *ot)) == NULL) { (void) sprintf (PY_pepy, "out of memory"); return NOTOK; } if ((ot -> ot_text = strdup (*vec++)) == NULL || (ot -> ot_id = strdup (*vec++)) == NULL) { (void) sprintf (PY_pepy, "out of memory"); return NOTOK; } if ((ot -> ot_syntax = text2syn (*vec)) == NULL && lexequ (*vec, "Aggregate") && debug) fprintf (stderr, "warning: object \"%s\" has unknown SYNTAX \"%s\"\n", ot -> ot_text, *vec); vec++; if (lexequ (*vec, "read-only") == 0) ot -> ot_access = OT_RDONLY; else if (lexequ (*vec, "read-write") == 0) ot -> ot_access = OT_RDWRITE; else if (lexequ (*vec, "none") && debug) fprintf (stderr, "warning: object \"%s\" has unknown ACCESS \"%s\"\n", ot -> ot_text, *vec); vec++; if (lexequ (*vec, "mandatory") == 0) ot -> ot_status = OT_MANDATORY; else if (lexequ (*vec, "optional") == 0) ot -> ot_status = OT_OPTIONAL; else if (lexequ (*vec, "deprecated") == 0) ot -> ot_status = OT_DEPRECATED; else if (lexequ (*vec, "obsolete") && debug) fprintf (stderr, "warning: object \"%s\" has unknown STATUS \"%s\"\n", ot -> ot_text, *vec); vec++; ot -> ot_chain = Tbuckets[i = THASH (ot -> ot_text)]; Tbuckets[i] = ot; return OK; } /* \f */ OID text2oid (name) char *name; { int i, j; register unsigned int *ip, *jp; unsigned int elements[NELEM + 1]; register char *cp; OID oid, new; for (cp = name + strlen (name) - 1; cp >= name; cp--) if (!isdigit (*cp) && *cp != '.') break; cp++; if (isdigit (*cp) && cp != name) for (cp++; *cp; cp++) if (*cp == '.') break; if (*cp == NULL) /* name */ i = 0; else if (cp == name) { /* 1.3.6.1.2.1.1.1.0 */ if ((i = str2elem (cp, elements)) < 2) return NULL; } else /* name.numbers */ if ((i = str2elem (cp + 1, elements)) < 1) return NULL; if (cp != name) { *cp = NULL; if ((oid = resolve (name, NULLOT)) == NULLOID) return NULL; if (i == 0) return oid; j = oid -> oid_nelem; } else oid = NULL, j = 0; if ((new = (OID) malloc (sizeof *new)) == NULLOID) { oid_free (oid); return NULL; } if ((ip = (unsigned int *) malloc ((unsigned) (i + j + 1) * sizeof *ip)) == NULL) { oid_free (oid); free ((char *) new); } new -> oid_elements = ip, new -> oid_nelem = i + j; if (oid) { for (j = 0, jp = oid -> oid_elements; j < oid -> oid_nelem; j++, jp++) *ip++ = *jp; oid_free (oid); } if (i > 0) for (j = 0, jp = elements; j < i; j++, jp++) *ip++ = *jp; new -> oid_nelem = ip - new -> oid_elements; return new; } static OID resolve (id, ot) char *id; register OT ot; { int i; unsigned int elements[NELEM + 1]; register char *cp; register OT ot2; struct OIDentifier oids; register OID oid = &oids; oid -> oid_elements = elements; if (cp = index (id, '.')) *cp = NULL; if (isdigit (*id)) { ot2 = NULLOT; oid -> oid_nelem = 1; oid -> oid_elements[0] = atoi (id); if (cp) *cp = '.'; } else { ot2 = text2obj (id); if (cp) *cp = '.'; if (ot2 == NULLOT || ot2 -> ot_name == NULLOID) return NULLOID; oid -> oid_nelem = ot2 -> ot_name -> oid_nelem; bcopy ((char *) ot2 -> ot_name -> oid_elements, (char *) oid -> oid_elements, oid -> oid_nelem * sizeof *elements); } if (cp) { if ((i = str2elem (++cp, oid -> oid_elements + oid -> oid_nelem)) < 1) return NULLOID; oid -> oid_nelem += i; if (ot && ot2) { /* XXX: not normalized... */ ot -> ot_sibling = ot2 -> ot_children; ot2 -> ot_children = ot; } } return oid_cpy (oid); } /* \f */ /* partial matches are made only on leaf nodes... */ static char *roots[] = { NULL, "iso", "ccitt", "joint-iso-ccitt" }; OT name2obj (oid) OID oid; { register int i, j; register unsigned *ip; register OID nm; register OT ot; if (oid == NULLOID || oid -> oid_nelem < 1 || (i = (ip = oid -> oid_elements)[0]) >= (sizeof roots / sizeof roots[0]) || (ot = text2obj (roots[i])) == NULL) return NULLOT; i = 0; while (ot) { if ((j = (nm = ot -> ot_name) -> oid_nelem) > oid -> oid_nelem) return NULLOT; if (bcmp ((char *) ip, (char *) (nm -> oid_elements + i), (j - i) * sizeof *ip)) ot = ot -> ot_sibling; else if (oid -> oid_nelem == j || ot -> ot_children == NULLOT) break; else { ot = ot -> ot_children; ip = oid -> oid_elements + j, i = j; } } return ot; } /* \f */ OT text2obj (text) char *text; { register OT ot; if (text == NULL || once_only == 0) return NULLOT; for (ot = Tbuckets[THASH (text)]; ot && strcmp (ot -> ot_text, text); ot = ot -> ot_chain) continue; return ot; } /* \f */ char *oid2ode (oid) OID oid; { register int i; register char *bp; register unsigned int *ip; register OID oid2; register OT ot; static char buffer[BUFSIZ]; if ((ot = name2obj (oid)) == NULLOT) return sprintoid (oid); (void) strcpy (bp = buffer, ot -> ot_text); bp += strlen (bp); for (ip = oid -> oid_elements + (oid2 = ot -> ot_name) -> oid_nelem, i = oid -> oid_nelem - oid2 -> oid_nelem; i-- > 0; ip++) { (void) sprintf (bp, ".%u", *ip); bp += strlen (bp); } return buffer; } /* \f */ OI name2inst (oid) OID oid; { static object_instance ois; register OI oi = &ois; if ((oi -> oi_type = name2obj (oi -> oi_name = oid)) == NULLOT) return NULLOI; return oi; } OI next2inst (oid) OID oid; { static object_instance ois; register OI oi = &ois; register OT ot; if (oid_cmp (oid, chain -> ot_name) <= 0) for (ot = anchor; ot; ot = ot -> ot_next) if (oid_cmp (oid, ot -> ot_name) <= 0) { oi -> oi_name = (oi -> oi_type = ot) -> ot_name; return oi; } return NULLOI; } /* \f */ OI text2inst (text) char *text; { static object_instance ois; register OI oi = &ois; static OID oid = NULLOID; if (oid) oid_free (oid), oid = NULLOID; if ((oid = text2oid (text)) == NULLOID) return NULLOI; if ((oi -> oi_type = name2obj (oi -> oi_name = oid)) == NULLOT) { if (debug) fprintf (stderr, "got name \"%s\", but not object\n", text); return NULLOI; } return oi; } /* \f MISCELLANY */ char *strdup (s) char *s; { char *p; if (p = malloc ((unsigned) (strlen (s) + 1))) (void) strcpy (p, s); return p; }