예제 #1
0
STATUS
MO_classid_index(i4 msg,
		 PTR cdata,
		 i4  linstance,
		 char *instance, 
		 PTR *instdata )
{
    STATUS stat = OK;
    MO_CLASS *cp;

    switch( msg )
    {
    case MO_GET:
	if( OK == (stat = MO_getclass( instance, &cp ) ) )
	    *instdata = (PTR)cp;
	break;

    case MO_GETNEXT:
	if( OK == ( stat = MO_nxtclass( instance, &cp ) ) )
	{
	    *instdata = (PTR)cp;
	    stat = MOstrout( MO_INSTANCE_TRUNCATED,
			     cp->node.key, linstance, instance );
	}
	break;

    default:
	stat = MO_BAD_MSG;
	break;
    }
    return( stat );
}
예제 #2
0
/*{
**  Name:	MOset - set value associated with an instance
**
**  Description:
**
**	Attempts to set the value associated with the instance.
**
**	If the call succeeds, it must also call the monitors for the
**	class with the MO_SET event, the instance id, and the new value.
**  Inputs:
**	 valid_perms
**		the roles currently in effect, to be and-ed with object
**		permissions to determine access rights.
**	 class
**		the class whose value should be altered.
**	 instance
**		the instance in question.
**	 val
**		pointer to the string containing the new value.
**  Outputs:
**	 none
**  Returns:
**	 OK
**		if the value was set
**	 MO_NO_INSTANCE
**		if the class is not attached
**	 MO_NO_WRITE
**		if the class may not be changed.
**	 other
**		error status returned by a method.
**  History:
**	23-sep-92 (daveb)
**	    documented
**	 6-Apr-04 (gordy)
**	    Permit access if MO_ANY_WRITE attribute is set.
**	24-Oct-05 (toumi01) BUG 115449
**	    Don't hold onto MO mutex if class' processing will try
**	    to take the mutex, and would thus deadlock on ourself.
*/
STATUS
MOset(i4 valperms,
      char *classid,
      char *instance,
      char *val )
{
    STATUS stat = OK;
    MO_CLASS *cp;
    PTR idata;

    MO_once();
    stat = MO_mutex();
    if( stat != OK )
	return( stat );
    MO_nset++;

    /* get class and instance data */

    if( OK == (stat = MO_getclass( classid, &cp ) ) )
    {
	if( (cp->perms & MO_ANY_WRITE) != 0  ||  
	    (valperms & MO_WRITE & cp->perms) != 0 )
	    stat = (*cp->idx)( MO_GET, cp->cdata, 0, instance, &idata );
	else
	    stat = MO_NO_WRITE;
    }

    if( stat == OK )
    {
	if (cp->cflags & MO_NO_MUTEX)
	    (VOID) MO_unmutex();
	stat = (*cp->set)( cp->offset, 0, val, cp->size, idata );
	if (cp->cflags & MO_NO_MUTEX)
	{
	    stat = MO_mutex();
	    if( stat != OK )
		return( stat );
	}
    }

    if( stat == OK )
	(VOID) MO_tell_class( cp, instance, val, MO_SET );

    (VOID) MO_unmutex();
    return( stat );
}
예제 #3
0
STATUS
MOtell_monitor( char *classid, char *instance, char *value, i4  msg )
{
    MO_CLASS *cp;
    STATUS ret_val = OK;

    MO_once();
    ret_val = MO_mutex();
    if( ret_val == OK )
    {
	ret_val = MO_getclass( classid, &cp );
	if( ret_val == OK && cp->monitor != NULL )
	    ret_val = MO_tell_class( cp, instance, value, msg );

	(VOID) MO_unmutex();
    }
    return( ret_val );
}
예제 #4
0
MO_MON_BLOCK *
MO_igetmon( char *instance )
{
    char classid[ 80 ];
    MO_CLASS *cp;
    char *p;
    u_i4 mon_data_val;

    for( p = classid; *instance && *instance != '.' ; )
	*p++ = *instance++;
    *p = EOS;
    cp = NULL;
    MO_getclass( classid, &cp );

    if( *instance )
	instance++;

    MO_str_to_uns( instance, &mon_data_val );

    return( MO_getmon( cp, (PTR)mon_data_val ) );
}
예제 #5
0
STATUS
MO_get(i4 valperms,
      char *classid,
      char *instance,
      i4  *lsbufp,
      char *sbuf,
      i4  *operms )
{
    STATUS stat;
    MO_CLASS *cp;
    PTR idata;

    MO_nget++;

    stat = OK;
    *sbuf = EOS;

    /* get class and instance data */

    if( OK == (stat = MO_getclass( classid, &cp ) ) )
    {
	if( (cp->perms & MO_ANY_READ) != 0  ||
	    (valperms & MO_READ & cp->perms) != 0 )
	    stat = (*cp->idx)( MO_GET, cp->cdata, 0, instance, &idata );
	else
	    stat = MO_NO_READ;
    }

    if( stat == OK )
       stat = (*cp->get)( cp->offset, cp->size, idata, *lsbufp, sbuf  );

    if( stat == OK || stat == MO_VALUE_TRUNCATED )
    {
	*operms = cp->perms;
        (VOID) MO_tell_class( cp, instance, sbuf, MO_GET );
    }
    return( stat );
}
예제 #6
0
STATUS
MOattach( i4  flags, char *classid, char *instance, PTR idata )
{
    MO_INSTANCE	*ip;
    MO_CLASS	*cp;
    STATUS	stat;

    stat = OK;

    if( MO_disabled )
	return( stat );

    MO_once();
    stat = MO_mutex();
    if( stat == OK )		/* got mutex */
    {
	do
	{
	    if( stat != OK )
		break;

	    MO_nattach++;

# ifdef xDEBUG
	    SIprintf("attach %s:%s object %p\n",
		     classid,
		     instance,
		     idata );
# endif

	    /* check for special error cases */

	    ip = MO_getinstance( classid, instance );
	    if( ip != NULL )
	    {
		stat = MO_ALREADY_ATTACHED;
		break;
	    }

	    /* Get class, error if missing */

	    if( OK != MO_getclass( classid, &cp ) )
	    {
		stat = MO_NO_CLASSID;
		break;
	    }

	    /* Release mutex to prevent deadlock in MO_alloc call */
	    (VOID) MO_unmutex();
	    ip = (MO_INSTANCE *)MO_alloc( sizeof(*ip), &stat );
            stat = MO_mutex();
	    if( NULL == ip )
		break;

	    ip->classdef = cp;
	    ip->iflags = flags;
	    if( (flags & MO_INSTANCE_VAR) == 0 )
	    {
		ip->instance = instance;
	    }
	    else
	    {
		ip->instance = MO_defstring( instance, &stat );
		if( ip->instance == NULL )
		{
		    MO_free( (PTR)ip, sizeof(*ip) );
		    break;
		}
	    }
	    ip->idata = idata;
	    ip->node.key = (PTR)ip;

	    (VOID) SPenq( &ip->node, MO_instances );

	} while( FALSE );

	(VOID) MO_unmutex();

	/* Attach twin if needed */

	if( stat == OK && cp->twin != NULL && !CMdigit( (char *)cp->node.key ) )
	    stat = MOattach( flags, cp->twin->node.key, instance, idata );
    }

# if xDEBUG
    if( stat != OK )
	TRdisplay("attach (%s:%s) failed status %d\n",
		  classid, instance, stat );
# endif

    if( stat == OK )
    {
	if ( (stat = MO_mutex()) == OK)
	{
	    (VOID) MO_tell_class( cp, instance, (char *)NULL, MO_ATTACH );
            MO_unmutex ();
	}
    }

    return( stat );
}
예제 #7
0
STATUS
MO_getnext(i4 valperms,
	   i4  lclassid,
	   i4  linstance,
	   char *classid,
	   char *instance,
	   i4  *lsbufp,
	   char *sbuf,
	   i4  *operms )
{
    STATUS stat = OK;
    STATUS xstat = OK;

    MO_INSTANCE *ip;
    MO_CLASS *cp;		/* this class */
    PTR idata;

    MO_ngetnext++;

# ifdef xDEBUG
    SIprintf("getnext entry: %s:%s\n", classid, instance );
# endif

    ip = NULL;
    cp = NULL;
    *sbuf = EOS;

    if( *instance != EOS )
    {
	ip = MO_getinstance( classid, instance );
	if( ip != NULL )
	    cp = ip->classdef;
	else if( OK != MO_getclass( classid, &cp ) )
	    stat = MO_NO_CLASSID;
    }
    else if( *classid != EOS && OK != MO_getclass( classid, &cp ) )
    {
	stat = MO_NO_CLASSID;
    }

    /*
    ** Now do the real work:  Given the starting point implied
    ** by ip and cp, find the next visible instance.
    */
    if( stat == OK )
    {
	if( cp == NULL )	/* start with first class */
	{
	    cp = (MO_CLASS *) SPfhead( MO_classes );
	    ip = NULL;
	}

	/*
	 ** Loop over classes looking for the next valid instance.
	 **
	 ** On exit, if cp != NULL, it's the class of the found instance;
	 **	if NULL, then we never found a good instance.
	 */
	for( ; cp != NULL ; cp = (MO_CLASS *)SPnext( &cp->node, MO_classes ) )
	{
	    if( (cp->perms & MO_ANY_READ) != 0  ||
		(valperms & MO_READ & cp->perms) != 0 )
	    {
		stat = (*cp->idx)( MO_GETNEXT, cp->cdata,
			      linstance, instance, &idata );
		if( stat == OK )
		{
		    stat = (*cp->get)( cp->offset,
				      cp->size, idata,
				      *lsbufp, sbuf  );
		    if( stat == OK )
			break;
		}
	    }
	    /* Now caller's ip and instance are bogus; set to search state */

	    ip = NULL;
	    *instance = EOS;
	}

	if( cp == NULL )
	    stat = MO_NO_NEXT;

	if( stat == OK || MO_IS_TRUNCATED( stat ) )
	    xstat = MOstrout( MO_CLASSID_TRUNCATED,
			      cp->node.key, lclassid, classid );

	if( stat == OK )
	    stat = xstat;
    }

    *lsbufp = (i4)STlength( sbuf );

    if( stat == OK || stat == MO_VALUE_TRUNCATED )
    {
	*operms = cp->perms;
	(VOID) MO_tell_class( cp, instance, sbuf, MO_GET );
    }

# ifdef xDEBUG
    SIprintf("getnext exit: (%d) %s:%s - %s\n",
	     stat, classid, instance, sbuf );
# endif
    return( stat );
}
예제 #8
0
STATUS
MO_oid_set(i4 offset,
	   i4  luserbuf,
	   char *userbuf,
	   i4  objsize,
	   PTR object )
{
    STATUS	cl_stat = OK;
    MO_CLASS	*cp = (MO_CLASS *)object;
    MO_CLASS	*twin_cp;
    MO_INSTANCE	*ip;
    MO_INSTANCE	*next_ip;

    MO_CLASS_DEF	mo_class;

    do
    {
	/* if it has a twin already, error */
	if( cp->twin != NULL )
	{
	    cl_stat = MO_NO_WRITE;
	    break;
	}

	mo_class.flags = MO_CLASSID_VAR | cp->cflags;
	mo_class.classid = userbuf;
	mo_class.size = cp->size;
	mo_class.perms = cp->perms;
	mo_class.index = cp->index;
	mo_class.get = cp->get;
	mo_class.set = cp->set;
	mo_class.cdata = cp->cdata;
	mo_class.idx = cp->idx;
	if( OK != (cl_stat = MOclassdef( 1, &mo_class ) ) )
	    break;

	if( OK != (cl_stat = MO_getclass( userbuf, &twin_cp ) ) )
	    break;

	cp->twin = twin_cp;
	twin_cp->twin = cp;
	twin_cp->monitor = cp->monitor;

	/* now attach all objects of the class as twins */

	for( ip = (MO_INSTANCE *)SPfhead( MO_instances ); ip != NULL ; ip = next_ip )
	{
	    next_ip = (MO_INSTANCE *)SPfnext( (SPBLK *)ip );
	    if( ip->classdef == cp )
	    {
		/* create one for the twin. */
		cl_stat = MOattach( 0, twin_cp->node.key, ip->instance, ip->idata );
		if( cl_stat != OK )
		    break;

		if( next_ip->classdef != cp )
		    break;
	    }
	}
    } while( FALSE );
    return( cl_stat );
}
예제 #9
0
STATUS
MOset_monitor(	char *classid,
		PTR mon_data,
		char *qual_regexp,
		MO_MONITOR_FUNC *monitor,
		MO_MONITOR_FUNC **old_monitor )
{
    MO_MON_BLOCK *mp;		/* our monitor block */
    MO_MON_BLOCK *fmp;		/* first monitor block */
    MO_MON_BLOCK *pmp;		/* previous monitor block */
    MO_CLASS *cp;		/* class in question (not classid) */
    char *saved_qual = NULL;

    STATUS ret_val = OK;
    STATUS mutex_stat;

    mutex_stat = MO_mutex();
    do
    {
	if( mutex_stat != OK )
	    break;

	/* if we'll need it, save any qual_regexp string */

	if( monitor != NULL && qual_regexp != NULL )
	{
	    saved_qual = MO_defstring( qual_regexp, &ret_val );
	    if( saved_qual == NULL )
		break;

	    /* FIXME maybe compile it here too? */
	}

	/* locate the class def, we need it everywhere */

	if( (ret_val = MO_getclass( classid, &cp )) != OK )
	    break;

	/* see if this is a replacement for an existing monitor */

	mp = NULL;
	if( (mp = MO_getmon( cp, mon_data ) ) != NULL )
	{
	    /* yes, replace it with new values as appropriate */

	    *old_monitor = mp->monitor;
	    if( monitor == NULL ) /* delete this monitor */
	    {
		MO_delmon( mp );
	    }
	    else		/* replace this one's values */
	    {
		mp->monitor = monitor;
		mp->mon_data = mon_data;

		/* delete old qual string */
		if( mp->qual_regexp != NULL )
		    MO_delstring( mp->qual_regexp );
		mp->qual_regexp = saved_qual;
	    }
	}
	else if( monitor == NULL ) /* huh!? */
	{
	    ret_val = MO_BAD_MONITOR;
	    break;
	}
	else			/* make a new one and link it in. */
	{
	    *old_monitor = NULL;

	    /* if it's an OID, get the class def instead */

	    if( CMdigit( (char *)cp->node.key ) && cp->twin != NULL )
		cp = cp->twin;

	    /* get a new monitor block */

	    mp = (MO_MON_BLOCK *)MO_alloc( sizeof( *mp ), &ret_val );
	    if( mp == NULL )
		break;

	    /* fill in the new block, and link in to the tree */

	    mp->node.key = (PTR)mp;
	    mp->mo_class = cp;
	    mp->monitor = monitor;
	    mp->mon_data = mon_data;
	    mp->qual_regexp = saved_qual;
	    (void) SPenq( &mp->node, MO_monitors );

	    /* Fill in the class with first monitor for the class.
	       The loop below goes backwards until pmp is null or
	       doesn't have the same class definition.  When it exits,
	       fmp is at the first monitor block for the class */

	    for( fmp = mp;
		(pmp = (MO_MON_BLOCK *)SPfprev( &fmp->node )) != NULL &&
		pmp->mo_class == cp; fmp = pmp )
		continue;

	    fmp->mo_class->monitor = fmp;
	    if( cp->twin )
		cp->twin->monitor = fmp;
	}

    } while ( FALSE );

    if( mutex_stat != OK )
    {
	ret_val = mutex_stat;
    }
    else
    {
	if( ret_val == OK )
	    MO_nset_monitor++;
	else if( saved_qual != NULL )
	    MO_delstring( saved_qual );

	(void) MO_unmutex();
    }

    return( ret_val );
}