Exemplo n.º 1
0
int
TnmSetConfig(Tcl_Interp *interp, TnmConfig *config, ClientData object, int objc, Tcl_Obj *const objv[])
{
    int i, option, code;
    TnmTable *elemPtr;
    Tcl_Obj *listPtr;
    Tcl_Obj *objPtr;

    if (objc % 2) {
	Tcl_WrongNumArgs(interp, 2, objv, "?option value? ?option value? ...");
	return TCL_ERROR;
    }

    /*
     * First scan through the list of options to make sure that
     * we don't run on an unknown option later when we have 
     * already modified the object.
     */

    for (i = 2; i < objc; i += 2) {
	option = TnmGetTableKeyFromObj(interp, config->optionTable,
				       objv[i], "option");
	if (option < 0) {
	    return TCL_ERROR;
	}
    }

    /*
     * Now call the function to actually modify the object. Note,
     * this version does not rollback changes so an object might
     * end up in a half modified state.
     */
	
    for (i = 2; i < objc; i += 2) {
	option = TnmGetTableKeyFromObj(interp, config->optionTable,
				       objv[i], "option");
	code = (config->setOption)(interp, object, option, objv[i+1]);
	if (code != TCL_OK) {
	    return TCL_ERROR;
	}
    }

    /*
     * Create a new list which contains all the configuration
     * options and their current values.
     */

    listPtr = Tcl_GetObjResult(interp);
    for (elemPtr = config->optionTable; elemPtr->value; elemPtr++) {
	objPtr = (config->getOption)(interp, object, (int) elemPtr->key);
	if (objPtr) {
	    Tcl_ListObjAppendElement(interp, listPtr, 
				     Tcl_NewStringObj(elemPtr->value, -1));
	    Tcl_ListObjAppendElement(interp, listPtr, objPtr);
	}
    }
    return TCL_OK;
}
Exemplo n.º 2
0
int
TnmGetConfig(Tcl_Interp *interp, TnmConfig *config, ClientData object, int objc, Tcl_Obj *const objv[])
{
    int option;
    Tcl_Obj *objPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "option");
	return TCL_ERROR;
    }

    option = TnmGetTableKeyFromObj(interp, config->optionTable, 
				   objv[2], "option");
    if (option < 0) {
	return TCL_ERROR;
    }

    objPtr = (config->getOption)(interp, object, option);
    if (! objPtr) {
	Tcl_ResetResult(interp);
	Tcl_AppendResult(interp, "invalid option \"", 
			 Tcl_GetStringFromObj(objv[2], NULL), "\"", 
			 (char *) NULL);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, objPtr);
    return TCL_OK;
}
Exemplo n.º 3
0
Tcl_Obj*
TnmSnmpNorm(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags)
{
    int i, code, objc;
    Tcl_Obj **objv;
    Tcl_Obj *vbListPtr = NULL;

    /*
     * The following Tcl_Objs are allocated once and reused whenever
     * we need to expand a varbind list containing object identifiers
     * without any value or type elements.
     */

    static Tcl_Obj *nullType = NULL;
    static Tcl_Obj *zeroValue = NULL;
    static Tcl_Obj *nullValue = NULL;

    if (! nullType) {
	nullType = Tcl_NewStringObj("NULL", 4);
	Tcl_IncrRefCount(nullType);
    }
    if (! zeroValue) {
	zeroValue = Tcl_NewIntObj(0);
	Tcl_IncrRefCount(zeroValue);
    }
    if (! nullValue) {
	nullValue = Tcl_NewStringObj(NULL, 0);
	Tcl_IncrRefCount(nullValue);
    }

    /*
     * Split the varbind list into a list of varbinds. Create a
     * new Tcl list to hold the expanded varbind list.
     */

    code = Tcl_ListObjGetElements(interp, objPtr, &objc, &objv);
    if (code != TCL_OK) {
	goto errorExit;
    }

    vbListPtr = Tcl_NewListObj(0, NULL);

    for (i = 0; i < objc; i++) {
	int vbc, type;
	Tcl_Obj **vbv, *vbPtr;
	TnmOid* oidPtr;
	Tcl_Obj *oidObjPtr, *typeObjPtr, *valueObjPtr;
	TnmMibNode *nodePtr = NULL;

	/*
	 * Create a new varbind element in the expanded result list
	 * for each varbind.
	 */

	vbPtr = Tcl_NewListObj(0, NULL);
	Tcl_ListObjAppendElement(interp, vbListPtr, vbPtr);

	code = Tcl_ListObjGetElements(interp, objv[i], &vbc, &vbv);
	if (code != TCL_OK) {
	    goto errorExit;
	}

	/*
	 * Get the object identifier value from the first list
	 * element. Check the number of list elements and assign
	 * them to the oid, type and value variables.
	 */

	switch (vbc) {
	case 1:
	    oidObjPtr = vbv[0];
	    typeObjPtr = nullType;
	    valueObjPtr = nullValue;
	    break;
	case 2:
	    oidObjPtr = vbv[0];
	    typeObjPtr = NULL;
	    valueObjPtr = vbv[1];
	    break;
	case 3:
	    oidObjPtr = vbv[0];
	    typeObjPtr = vbv[1];
	    valueObjPtr = vbv[2];
	    break;
	default: {
		char msg[80];
		sprintf(msg, "illegal number of elements in varbind %d", i);
		Tcl_ResetResult(interp);
		Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 
				       msg, (char *) NULL);
		goto errorExit;
	    }
	}

	/*
	 * Check/resolve the object identifier and assign it to the
	 * result list. Make sure to make a deep copy if the object
	 * identifier value is shared since the string representation
	 * must be invalidated to ensure that hexadecimal
	 * sub-identifier are converted into decimal sub-identifier.
	 */

	oidPtr = TnmGetOidFromObj(interp, oidObjPtr);
	if (! oidPtr) {
	    goto errorExit;
	}
	if (Tcl_IsShared(oidObjPtr)) {
	    oidObjPtr = Tcl_DuplicateObj(oidObjPtr);
	}
	TnmOidObjSetRep(oidObjPtr, TNM_OID_AS_OID);
	Tcl_InvalidateStringRep(oidObjPtr);
	Tcl_ListObjAppendElement(interp, vbPtr, oidObjPtr);

	/* 
	 * Lookup the type in the MIB if there is no type given in the
	 * varbind element.
	 */

	if (! typeObjPtr) {
	    int syntax;
	    nodePtr = TnmMibNodeFromOid(oidPtr, NULL);
	    if (! nodePtr) {
		char msg[80];
		sprintf(msg, "failed to lookup the type for varbind %d", i);
		Tcl_ResetResult(interp);
		Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 
				       msg, (char *) NULL);
		goto errorExit;
	    }
	    syntax = (nodePtr->typePtr && nodePtr->typePtr->name)
		? nodePtr->typePtr->syntax : nodePtr->syntax;

	    typeObjPtr = Tcl_NewStringObj(
		TnmGetTableValue(tnmSnmpTypeTable, (unsigned) syntax), -1);
	}

	type = TnmGetTableKeyFromObj(NULL, tnmSnmpTypeTable, 
				     typeObjPtr, NULL);
	if (type == -1) {
	    type = TnmGetTableKeyFromObj(NULL, tnmSnmpExceptionTable,
					 typeObjPtr, NULL);
	    if (type == -1) {
		char msg[80];
	    invalidType:
		sprintf(msg, "illegal type in varbind %d", i);
		Tcl_ResetResult(interp);
		Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), 
				       msg, (char *) NULL);
		goto errorExit;
	    }
	}

	Tcl_ListObjAppendElement(interp, vbPtr, typeObjPtr);

	/*
	 * Check the value and perform any conversions needed to
	 * convert the value into the base type representation.
	 */

	switch (type) {
	case ASN1_INTEGER: {
	    long longValue;
	    code = Tcl_GetLongFromObj(interp, valueObjPtr, &longValue);
	    if (code != TCL_OK) {
		if (! nodePtr) {
		    nodePtr = TnmMibNodeFromOid(oidPtr, NULL);
		}
		if (nodePtr) {
		    Tcl_Obj *value;
		    value = TnmMibScanValue(nodePtr->typePtr, nodePtr->syntax, 
					    valueObjPtr);
		    if (! value) {
			goto errorExit;
		    }
		    Tcl_ResetResult(interp);
		    code = Tcl_GetLongFromObj(interp, value, &longValue);
		}
		if (code != TCL_OK) {
		    goto errorExit;
		}
		valueObjPtr = Tcl_NewLongObj(longValue);
	    }
	    if (flags & TNM_SNMP_NORM_INT) {
		if (! nodePtr) {
		    nodePtr = TnmMibNodeFromOid(oidPtr, NULL);
		}
		if (nodePtr && nodePtr->typePtr) {
		    Tcl_Obj *newPtr;
		    newPtr = TnmMibFormatValue(nodePtr->typePtr,
					       nodePtr->syntax,
					       valueObjPtr);
		    if (newPtr) {
			valueObjPtr = newPtr;
		    }
		}
	    }
	    break;
	}
	case ASN1_COUNTER32:
	case ASN1_GAUGE32:
	case ASN1_TIMETICKS: {
	    TnmUnsigned32 u;
	    code = TnmGetUnsigned32FromObj(interp, valueObjPtr, &u);
	    if (code != TCL_OK) {
		goto errorExit;
	    }
	    break;
	}
	case ASN1_COUNTER64: {
	    TnmUnsigned64 u;
	    code = TnmGetUnsigned64FromObj(interp, valueObjPtr, &u);
	    if (code != TCL_OK) {
		goto errorExit;
	    }
	    break;
	}
	case ASN1_IPADDRESS: {
            if (TnmGetIpAddressFromObj(interp, valueObjPtr) == NULL) {
		goto errorExit;
	    }
	    Tcl_InvalidateStringRep(valueObjPtr);
	    break;
	}
	case ASN1_OBJECT_IDENTIFIER:
	    if (! TnmGetOidFromObj(interp, valueObjPtr)) {
		goto errorExit;
	    }
	    if (Tcl_IsShared(valueObjPtr)) {
		valueObjPtr = Tcl_DuplicateObj(valueObjPtr);
	    }
	    if (flags & TNM_SNMP_NORM_OID) {
		TnmOidObjSetRep(valueObjPtr, TNM_OID_AS_NAME);
	    } else {
		TnmOidObjSetRep(valueObjPtr, TNM_OID_AS_OID);
	    }
	    Tcl_InvalidateStringRep(valueObjPtr);
	    break;
	case ASN1_OCTET_STRING: {
	    int len;
	    if (! nodePtr) {
		nodePtr = TnmMibNodeFromOid(oidPtr, NULL);
	    }
	    if (nodePtr) {
		Tcl_Obj *scan;
		scan = TnmMibScanValue(nodePtr->typePtr, nodePtr->syntax, 
				      valueObjPtr);
		if (scan) {
		    valueObjPtr = scan;
		}
	    }
	    if (TnmGetOctetStringFromObj(interp, valueObjPtr, &len) == NULL) {
		goto errorExit;
	    }
	    Tcl_InvalidateStringRep(valueObjPtr);
	    break;
	}
	case ASN1_NULL:
	    valueObjPtr = nullValue;
	    break;
	default:
	    goto invalidType;
	}
	
	Tcl_ListObjAppendElement(interp, vbPtr, valueObjPtr);
    }

    return vbListPtr;

 errorExit:
    if (vbListPtr) {
	Tcl_DecrRefCount(vbListPtr);
    }
    return NULL;
}