|
|
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;
}