DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T o

⟦0448ffb05⟧ TextFile

    Length: 20033 (0x4e41)
    Types: TextFile
    Names: »osimic.c«

Derivation

└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
    └─⟦e83f91978⟧ »EurOpenD22/isode/osimis-2.0.tar.Z« 
        └─⟦d846658bd⟧ 
            └─⟦this⟧ »osimis/smap/osimic.c« 

TextFile

/*
 * Copyright (c) 1988 University College London
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * by the Department of Computer Science, University College London.
 * The name of the University may not be used to
 * endorse or promote products derived from this software without
 * specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* osimic operations */

/*
 * By George Pavlou, October 1988
 */

#include <stdio.h>
#include <ctype.h>
#include "isode/psap.h"
#include "isode/rosap.h"
#include "msap.h"
#include "microscope.h"


char  *errmsg[] = {
    "no error",
    "object does no longer exist",
    "no parent object",
    "no subordinate objects",
    "no such entry",
    "object has got no attributes",
    "object can not be modified",
    "attribute can not be modified",
    "out of memory",
    "fatal error",
    "host not supported",
    "can't establish management association",
    "illegal operation"
};


PositionD  *objinst2positionD();
AttrPairs  *subords2attrpairs(), *mobject2attrpairs();


static MIBposition  pos;
static int  msd;

extern char host[];


int  init_position (positionD, error)
PositionD  *positionD;
Error  *error;
{
    PositionD  *tposD;
    MO_ID  *objid2inst();

    isodesetailor("./smaptailor");

    if ((msd = m_init(host)) == NOTOK) {        /* open mgmt connection */
	error->err_type = noMgmtConnection;
	sprintf(error->err_msg, "Error: %s", errmsg[11]);
	return NOTOK;
    }

    pos.objinst = objid2inst(M_SYSTEM, NULL);

    if ((tposD = objinst2positionD(pos.objinst)) == (PositionD *) NULL) {
	error->err_type = fatalError;
	return NOTOK;
    }
    strcpy(positionD->pos_type,  tposD->pos_type);
    strcpy(positionD->pos_value, tposD->pos_value);
    cfree(tposD);

    return OK;
}


terminate (sig)
int sig;
{
    m_term(msd);
    exit(sig);
}


int  mib_ascend (positionD, error)
PositionD  *positionD;
Error  *error;
{
    PositionD  *tposD;

    if (pos.mobj.type == M_SYSTEM) {
	error->err_type = noParentObject;
	sprintf(error->err_msg, "Error: %s", errmsg[2]);
	return NOTOK;
    }

    objinst2parent(pos.objinst);
    pos.mobj.type = objinst2type(pos.objinst);

    if ((tposD = objinst2positionD(pos.objinst)) == (PositionD *) NULL) {
	error->err_type = fatalError;
	return NOTOK;
    }
    strcpy(positionD->pos_type,  tposD->pos_type);
    strcpy(positionD->pos_value, tposD->pos_value);

    cfree(tposD);
    free_mobjD(&pos.mobj);
    moid_free(pos.subords);
    pos.subords = (MO_ID *) NULL;

    return OK;
}


int  mib_descend (entry, positionD, error)
int  entry;
PositionD  *positionD;
Error  *error;
{
    MO_ID *rdn = pos.subords;
    PositionD  *tposD;

    if (pos.mobj.type == RPCTL || pos.mobj.type == C_THLD) {
	error->err_type = noSubordinateObjects;
	sprintf(error->err_msg, "%s", errmsg[3]);
	return NOTOK;
    }

    while (entry--)
	if ((rdn = rdn->Next) == (MO_ID *) NULL) {
	    error->err_type = noSuchEntry;
	    sprintf(error->err_msg, "Error: %s", errmsg[4]);
	    return NOTOK;
	}

    objinst2subord(pos.objinst, rdn);
    pos.mobj.type = objinst2type(pos.objinst);

    tposD = objinst2positionD(pos.objinst);
    strcpy(positionD->pos_type,  tposD->pos_type);
    strcpy(positionD->pos_value, tposD->pos_value);

    cfree(tposD);
    free_mobjD(&pos.mobj);
    moid_free(pos.subords);
    pos.subords = (MO_ID *) NULL;

    return OK;
}


AttrPairs  *list_subords (positionD, error)
PositionD  *positionD;
Error  *error;
{
    struct MSAPindication  mis;
    DN  subords;
    static reqid = 0;

    if (SubordinateListGetRequest(pos.mobj.type, pos.objinst, msd, reqid++)
		== NOTOK) {
	error->err_type = fatalError;
	sprintf(error->err_msg, "Error: %s", errmsg[9]);
	return (AttrPairs *) NULL;
    }

    if (M_WaitReq(msd, NOTOK, &mis) == NOTOK) {
	advise(NULLCP, "M_WaitReq failed: reason = %s",
						mis.mi_preject.mr_data);
	error->err_type = fatalError;
	sprintf(error->err_msg, "Error: %s", errmsg[9]);
	return (AttrPairs *) NULL;
    }

    if (mis.mi_type != MI_GET_RES) {
	if (mis.mi_type == MI_ERROR
			&& mis.mi_errtype == m_noSuchObjectInstance) {
	    mib_ascend(positionD, error);       /* object no longer exists */
	    error->err_type = objectDoesNotExist;
	    sprintf(error->err_msg, "Error: %s", errmsg[1]);
	}
	else {          /* any other indications or errors */
	    error->err_type = fatalError;
	    sprintf(error->err_msg, "Error: %s", errmsg[9]);
	}
	return (AttrPairs *) NULL;
    }

    moid_free(pos.subords);
    pos.subords = (MO_ID *) NULL;

    if (decode_IF_RDNSequence(mis.mi_getr.result.gr_attrs[0].mp_val,
			1, NULLIP, NULLVP, &subords)
		== NOTOK) {
	error->err_type = fatalError;
	sprintf(error->err_msg, "Error: %s", errmsg[9]);
	return (AttrPairs *) NULL;
    }
    dn_decode(subords);
    pos.subords = dn2moid(subords);
    dn_free(subords);

    return subords2attrpairs(pos.subords, error);
}


AttrPairs  *view_mobject (positionD, error)
PositionD  *positionD;
Error  *error;
{
    struct MSAPindication  mis;
    static reqid = 0;

    if (ManagedObjectGetRequest(pos.mobj.type, pos.objinst, msd, reqid++)
		== NOTOK) {
	error->err_type = fatalError;
	sprintf(error->err_msg, "Error: %s", errmsg[9]);
	return (AttrPairs *) NULL;
    }

    if (M_WaitReq(msd, NOTOK, &mis) == NOTOK) {
	advise(NULLCP, "M_WaitReq failed: reason = %s",
						mis.mi_preject.mr_data);
	error->err_type = fatalError;
	sprintf(error->err_msg, "Error: %s", errmsg[9]);
	return (AttrPairs *) NULL;
    }

    if (mis.mi_type != MI_GET_RES) {
	if (mis.mi_type == MI_ERROR &&
			mis.mi_errtype == m_noSuchObjectInstance) {
		mib_ascend(positionD, error);	/* object no longer exists */
		error->err_type = objectDoesNotExist;
		sprintf(error->err_msg, "Error: %s", errmsg[1]);
	}
	else {		/* any other indications or errors */
	    error->err_type = fatalError;
	    sprintf(error->err_msg, "Error: %s", errmsg[9]);
	}
	return (AttrPairs *) NULL;
    }

    free_mobjD(&pos.mobj);
    if (parseManagedObject(&pos.mobj, mis.mi_getr.result.gr_attrs)
		== NOTOK) {
	error->err_type = fatalError;
	sprintf(error->err_msg, "Error: %s", errmsg[9]);
	return (AttrPairs *) NULL;
    }

    return mobject2attrpairs(&pos.mobj, error);
}


/* ARGSUSED */

int  check_attribute (entry, error)
int  entry;
Error  *error;
{
    /* only threshold attributes are modifiable at present */

    if (pos.mobj.type == C_THLD || pos.mobj.type == G_THLD)
	return OK;

    error->err_type = objectNotModifiable;
    sprintf(error->err_msg, "Error: %s", errmsg[6]);
    return NOTOK;
}


AttrPairs  *modify_attribute (entry, modify, value, positionD, error)
int  entry;
ModifyOp  modify;
char  *value;
PositionD  *positionD;
Error  *error;
{
    struct MSAPindication  mis;
    static reqid = 0;
    MIDent class;
    MName  inst;
    int  i, multivalue = 0;
    CMISparam attr;
    OID  objtype2class();

    /* find out which attribute was modified, validate mode and encode */

    switch (pos.mobj.type) {
	case C_THLD:
	    for (i = 0; i < 10; i++) {
		if (pos.mobj.cthld->compLevels[i] == COMP_LEVEL_FREE)
		    break;
		multivalue++;
	    }

	    if (multivalue && entry >= multivalue + 2 ||
			!multivalue && entry > 2) {
		error->err_type = noSuchEntry;
		sprintf(error->err_msg, "Error: %s", errmsg[4]);
		return (AttrPairs *) NULL;
	    }

	    if (multivalue == 0)
		attr.mp_id.mid_local = entry + 2;
	    else
	    if (entry < multivalue)
		attr.mp_id.mid_local = 2;
	    else
		attr.mp_id.mid_local = entry - multivalue + 3;

	    if (attr.mp_id.mid_local == 2) {   /* comparisonLevel */
		if (multivalue == 0 &&
			(modify == m_removeValue || modify == m_replace)) {
		    error->err_type = illegalOperation;
		    sprintf(error->err_msg, "Error: %s - only add",
								errmsg[12]);
		    return (AttrPairs *) NULL;
		}
		else
		if (multivalue == 10 && modify == m_addValue) {
		    error->err_type = illegalOperation;
		    sprintf(error->err_msg, "Error: no more than 10 \
compLevels - only remove or replace");
		    return (AttrPairs *) NULL;
		}
	    }
	    else                        /* offsetValue or onoffSwitch */
		if (modify == m_addValue || modify == m_removeValue) {
		    error->err_type = illegalOperation;
		    sprintf(error->err_msg, "Error: %s - only replace",
								errmsg[12]);
		    return (AttrPairs *) NULL;
		}

	    switch (modify) {
		case m_addValue:
		    pos.mobj.cthld->compLevels[multivalue] = atoi(value);
		    if (multivalue + 1 < 10)
			pos.mobj.cthld->compLevels[multivalue+1] =
							COMP_LEVEL_FREE;
		    build_MIB_ComparisonLevels(&attr.mp_val, 1,
				NULL, NULLCP, pos.mobj.cthld->compLevels);
		    modify = m_replace;
		    break;

		case m_removeValue:
		    pos.mobj.cthld->compLevels[entry] = COMP_LEVEL_FREE;
		    for (i = entry+1; i < 10; i++) {
			pos.mobj.cthld->compLevels[i-1] =
					pos.mobj.cthld->compLevels[i];
			if (pos.mobj.cthld->compLevels[i] == COMP_LEVEL_FREE)
			    break;
			pos.mobj.cthld->compLevels[i] = COMP_LEVEL_FREE;
		    }
		    build_MIB_ComparisonLevels(&attr.mp_val, 1,
				NULL, NULLCP, pos.mobj.cthld->compLevels);
		    modify = m_replace;
		    break;

		case m_replace:
		    switch (attr.mp_id.mid_local) {
			case 2:
			    pos.mobj.cthld->compLevels[entry] = atoi(value);
			    build_MIB_ComparisonLevels(&attr.mp_val, 1,
				NULL, NULLCP, pos.mobj.cthld->compLevels);
			    break;
			case 3:
			    pos.mobj.cthld->offsetValue = atoi(value);
			    build_MIB_OffsetValue(&attr.mp_val, 1,
				NULL, NULLCP, &pos.mobj.cthld->offsetValue);
			    break;
			case 4:
			    pos.mobj.cthld->onoffSwitch = atoi(value);
			    build_MIB_OnoffSwitch(&attr.mp_val, 1,
				NULL, NULLCP, &pos.mobj.cthld->onoffSwitch);
			    break;
		    }
		    break;
	    }
	    break;

	case G_THLD:
	    for (i = 0; i < 10; i++) {
		if (pos.mobj.gthld->compLevels[i] == COMP_LEVEL_FREE)
		    break;
		multivalue++;
	    }

	    if (multivalue && entry >= multivalue + 2 ||
			!multivalue && entry > 2) {
		error->err_type = noSuchEntry;
		sprintf(error->err_msg, "Error: %s", errmsg[4]);
		return (AttrPairs *) NULL;
	    }

	    if (multivalue == 0)
		attr.mp_id.mid_local = entry + 2;
	    else
	    if (entry < multivalue)
		attr.mp_id.mid_local = 2;
	    else
		attr.mp_id.mid_local = entry - multivalue + 3;

	    if (attr.mp_id.mid_local == 2) {   /* comparisonLevel */
		if (multivalue == 0 &&
			(modify == m_removeValue || modify == m_replace)) {
		    error->err_type = illegalOperation;
		    sprintf(error->err_msg, "Error: %s - only add",
								errmsg[12]);
		    return (AttrPairs *) NULL;
		}
		else
		if (multivalue == 10 && modify == m_addValue) {
		    error->err_type = illegalOperation;
		    sprintf(error->err_msg, "Error: no more than 10 \
compLevels - only remove or replace");
		    return (AttrPairs *) NULL;
		}
	    }
	    else                        /* hysterInterval or onoffSwitch */
		if (modify == m_addValue || modify == m_removeValue) {
		    error->err_type = illegalOperation;
		    sprintf(error->err_msg, "Error: %s - only replace",
								errmsg[12]);
		    return (AttrPairs *) NULL;
		}

	    switch (modify) {
		case m_addValue:
		    pos.mobj.gthld->compLevels[multivalue] = atoi(value);
		    if (multivalue + 1 < 10)
			pos.mobj.gthld->compLevels[multivalue+1] =
							COMP_LEVEL_FREE;
		    build_MIB_ComparisonLevels(&attr.mp_val, 1,
				NULL, NULLCP, pos.mobj.gthld->compLevels);
		    modify = m_replace;
		    break;

		case m_removeValue:
		    pos.mobj.gthld->compLevels[entry] = COMP_LEVEL_FREE;
		    for (i = entry+1; i < 10; i++) {
			pos.mobj.gthld->compLevels[i-1] =
					pos.mobj.gthld->compLevels[i];
			if (pos.mobj.gthld->compLevels[i] == COMP_LEVEL_FREE)
			    break;
			pos.mobj.gthld->compLevels[i] = COMP_LEVEL_FREE;
		    }
		    build_MIB_ComparisonLevels(&attr.mp_val, 1,
				NULL, NULLCP, pos.mobj.gthld->compLevels);
		    modify = m_replace;
		    break;

		case m_replace:
		    switch (attr.mp_id.mid_local) {
			case 2:
			    pos.mobj.gthld->compLevels[entry] = atoi(value);
			    build_MIB_ComparisonLevels(&attr.mp_val, 1,
				NULL, NULLCP, pos.mobj.gthld->compLevels);
			    break;
			case 3:
			    pos.mobj.gthld->hysterInterval = atoi(value);
			    build_MIB_HysteresisInterval(&attr.mp_val, 1,
				NULL, NULLCP,&pos.mobj.gthld->hysterInterval);
			    break;
			case 4:
			    pos.mobj.gthld->onoffSwitch = atoi(value);
			    build_MIB_OnoffSwitch(&attr.mp_val, 1,
				NULL, NULLCP, &pos.mobj.gthld->onoffSwitch);
			    break;
		    }
		    break;
	    }
	    break;

	case RPCTL:     /* it will not be modified at present */
	{   destinationS *dest = pos.mobj.rpctl->listofdests;

	    while (dest != (destinationS *) NULL) {
		multivalue++;
		dest = dest->Next;
	    }
	}
	    if (entry >= multivalue) {
		error->err_type = noSuchEntry;
		sprintf(error->err_msg, "Error: %s", errmsg[4]);
		return (AttrPairs *) NULL;
	    }

	    attr.mp_id.mid_local  = 2;
	    /* newval and oldval need to be set here... */
	    /* also the new destination list... */
	    break;

	default:
	    error->err_type = objectNotModifiable;
	    sprintf(error->err_msg, "Error: %s", errmsg[6]);
	    return (AttrPairs *) NULL;
    }

    attr.mp_id.mid_type = MID_LOCAL;
    attr.mp_modify = modify;
    class.mid_type = MID_GLOBAL;
    class.mid_global = objtype2class(pos.mobj.type);
    inst.mn_type = MN_DN;
    inst.mn_dn = moid2dn(pos.objinst);

    /* do SET */
    if (M_SetC(msd, reqid++, &class, &inst, NULLSCOPE, NULLFILTER,
			NULLACCESS, s_bestEffort, 1, &attr, &mis) == NOTOK) {
	error->err_type = fatalError;
	sprintf(error->err_msg, "Error: %s", errmsg[9]);
	return (AttrPairs *) NULL;
    }

    pe_free(attr.mp_val);
    oid_free(class.mid_global);
    dn_free(inst.mn_dn);

    if (M_WaitReq(msd, NOTOK, &mis) == NOTOK) {
	advise(NULLCP, "M_WaitReq failed: reason = %s",
					mis.mi_preject.mr_data);
	error->err_type = fatalError;
	sprintf(error->err_msg, "Error: %s", errmsg[9]);
	return (AttrPairs *) NULL;
    }

    if (mis.mi_type != MI_SET_RES) {
	if (mis.mi_type == MI_ERROR
			&& mis.mi_errtype == m_noSuchObjectInstance) {
	    mib_ascend(positionD, error);       /* object no longer exists */
	    error->err_type = objectDoesNotExist;
	    sprintf(error->err_msg, "Error: %s", errmsg[1]);
	}
	else {          /* any other indications or errors */
	    error->err_type = fatalError;
	    sprintf(error->err_msg, "Error: %s", errmsg[9]);
	}
	return (AttrPairs *) NULL;
    }

    /* 'view' new attributes locally */

    return mobject2attrpairs(&pos.mobj, error);
}


int  validate_input (val)
register char  *val;
{
    register char *cp = val;
    int  i = 0;

    while (*cp++ == ' ');               /* ignore leading blanks */
    cp--;

    /* check for "on" or "off" alphanumeric input */

    if (strncmp(cp, "on", 2) == 0) {
	strcpy(val, "1");
	return OK;
    }
    else
    if (strncmp(cp, "off", 3) == 0) {
	strcpy(val, "0");
	return OK;
    }

    /* accept numeric input only */

    while (*cp) {
	if (isdigit(*cp))
	    val[i++] = *cp++;
	else
	if (*cp == '\0' || *cp == ' ')
	    break;                      /* ignore trailing blanks and other */
	else {
	    *val = '\0';
	    return NOTOK;
	}
    }
    val[i] = '\0';

    if (*val == '\0')
	return NOTOK;
    return OK;
}


PositionD  *objinst2positionD (objinst)
MO_ID  *objinst;
{
    register char  *typebuf, *valuebuf;
    char buf[10];
    int  id;
    PositionD  *pos;
    MO_ID *tinst = objinst;

    if ((pos = (PositionD *) calloc(1, sizeof(PositionD)))
		== (PositionD *) NULL)
	return (PositionD *) NULL;

    typebuf  = pos->pos_type;
    valuebuf = pos->pos_value;


    /* Level 0: M_SYSTEM */

    if (oid_cmp(&tinst->rdntype, str2oid("2.37.1.1.1")) == 0) {
	strcpy(typebuf, "system  ");
	sprintf(valuebuf, "%-8.8s", host);
	typebuf  += 8;
	valuebuf += 8;
    }
    else {
	advise(NULLCP, "objinst2positionD: bad inst");
	cfree(pos);
	return (PositionD *) NULL;
    }

    if ((tinst = tinst->Next) == (MO_ID *) NULL)
	return pos;


    /* Level 1: T_SUBSYS or RPCTL */

    if (oid_cmp(&tinst->rdntype, str2oid("2.37.1.2.1")) == 0) {
	strcpy(typebuf, "layer     ");
	strcpy(valuebuf, "transport ");
	typebuf  += 10;
	valuebuf += 10;
    }
    else
    if (oid_cmp(&tinst->rdntype, str2oid("2.37.3.3.1")) == 0) {
	bcopy(&tinst->rdnval[1], &id, sizeof(int));
	strcpy(typebuf, "repctl  ");
	sprintf(valuebuf, "%-8d", id);
	typebuf  += 8;
	valuebuf += 8;
	if (tinst->Next != (MO_ID *) NULL) {
	    /* RPCTL has got no subordinates */
	    advise(NULLCP, "objinst2positionD: bad inst");
	    cfree(pos);
	    return (PositionD *) NULL;
	}
    }
    else {
	advise(NULLCP, "objinst2positionD: bad inst");
	cfree(pos);
	return (PositionD *) NULL;
    }

    if ((tinst = tinst->Next) == (MO_ID *) NULL)
	return pos;


    /* Level 2: T_ENTITY */

    if (oid_cmp(&tinst->rdntype, str2oid("2.37.1.3.1")) == 0) {
	strncpy(buf, &tinst->rdnval[1], 9);
	buf[9] = '\0';          /* in case rdnval is exactly 9 chars */
	strcpy(typebuf, "entity    ");
	sprintf(valuebuf, "%-10.10s", buf);

	typebuf  += 10;
	valuebuf += 10;
    }
    else {
	advise(NULLCP, "objinst2positionD: bad inst");
	cfree(pos);
	return (PositionD *) NULL;
    }

    if ((tinst = tinst->Next) == (MO_ID *) NULL)
	return pos;


    /* Level 3: T_EINV or RPCTL */

    if (oid_cmp(&tinst->rdntype, str2oid("2.37.1.4.1")) == 0) {
	bcopy(&tinst->rdnval[1], &id, sizeof(int));
	strcpy(typebuf, "entinv  ");
	sprintf(valuebuf, "%-8d", id);
	typebuf  += 8;
	valuebuf += 8;
    }
    else
    if (oid_cmp(&tinst->rdntype, str2oid("2.37.3.3.1")) == 0) {
	bcopy(&tinst->rdnval[1], &id, sizeof(int));
	strcpy(typebuf, "repctl  ");
	sprintf(valuebuf, "%-8d", id);
	typebuf  += 8;
	valuebuf += 8;
	if (tinst->Next != (MO_ID *) NULL) {
	    /* RPCTL has got no subordinates */
	    advise(NULLCP, "objinst2positionD: bad inst");
	    cfree(pos);
	    return (PositionD *) NULL;
	}
    }
    else {
	advise(NULLCP, "objinst2positionD: bad inst");
	cfree(pos);
	return (PositionD *) NULL;
    }

    if ((tinst = tinst->Next) == (MO_ID *) NULL)
	return pos;


    /* Level 4: T_CEPT or C_THLD */

    if (oid_cmp(&tinst->rdntype, str2oid("2.37.1.5.1")) == 0) {
	bcopy(&tinst->rdnval[1], &id, sizeof(int));
	strcpy(typebuf, "cept    ");
	sprintf(valuebuf, "%-8d", id);
	typebuf  += 8;
	valuebuf += 8;
    }
    else
    if (oid_cmp(&tinst->rdntype, str2oid("2.37.3.1.1")) == 0) {
	strncpy(buf, &tinst->rdnval[1], 9);
	buf[9] = '\0';
	strcpy(typebuf, "cthld     ");
	sprintf(valuebuf, "%-10.10s", buf);
	typebuf  += 10;
	valuebuf += 10;
	if (tinst->Next != (MO_ID *) NULL) {
	    /* C_THLD has got no subordinates */
	    advise(NULLCP, "objinst2positionD: bad inst");
	    cfree(pos);
	    return (PositionD *) NULL;
	}
    }
    else {
	advise(NULLCP, "objinst2positionD: bad inst");
	cfree(pos);
	return (PositionD *) NULL;
    }

    if ((tinst = tinst->Next) == (MO_ID *) NULL)
	return pos;


    /* Level 5: C_THLD */

    if (oid_cmp(&tinst->rdntype, str2oid("2.37.3.1.1")) == 0) {
	strncpy(buf, &tinst->rdnval[1], 9);
	buf[9] = '\0';
	strcpy(typebuf, "cthld     ");
	sprintf(valuebuf, "%-10.10s", buf);
	typebuf  += 10;
	valuebuf += 10;
	if (tinst->Next != (MO_ID *) NULL) {
	    /* C_THLD has got no subordinates */
	    advise(NULLCP, "objinst2positionD: bad inst");
	    cfree(pos);
	    return (PositionD *) NULL;
	}
    }
    else {
	advise(NULLCP, "objinst2positionD: bad inst");
	cfree(pos);
	return (PositionD *) NULL;
    }

    if ((tinst = tinst->Next) == (MO_ID *) NULL)
	return pos;
    else {
	advise(NULLCP, "objinst2positionD: bad inst");
	cfree(pos);
	return (PositionD *) NULL;
    }
}