Esempio n. 1
0
/**
* Sets an attribute float in the material or a stage.
* @param stage The stage or -1 for the material.
* @param attribName The name of the attribute.
* @param value The value to set.
* @param addUndo Flag that specifies if the system should add an undo operation.
*/
void MaterialDoc::SetAttributeFloat(int stage, const char* attribName, float value, bool addUndo) {
	//Make sure we need to set the attribute
	float orig  = GetAttributeFloat(stage, attribName);
	if(orig != value) {

		idDict* dict;
		if(stage == -1) {
			dict = &editMaterial.materialData;
		} else {
			assert(stage >= 0 && stage < GetStageCount());
			dict = &editMaterial.stages[stage]->stageData;
		}

		dict->SetFloat(attribName, value);

		manager->AttributeChanged(this, stage, attribName);
		OnMaterialChanged();
	}
}
Esempio n. 2
0
/**
* Writes a set of material attributes to a file.
* @param stage The stage to write or -1 for the material.
* @param file The file where the stage should be wirtten.
* @param type The attribute grouping to use.
* @param indent The number of tabs to indent the text.
*/
void MaterialDoc::WriteMaterialDef(int stage, idFile_Memory* file, int type, int indent) {

	idStr prefix = "";
	for(int i = 0; i < indent; i++) {
		prefix += "\t";
	}

	MaterialDefList* defs = MaterialDefManager::GetMaterialDefs(type);
	for(int i = 0; i < defs->Num(); i++) {
		switch((*defs)[i]->type) {
			case MaterialDef::MATERIAL_DEF_TYPE_STRING:
				{
					idStr attrib = GetAttribute(stage, (*defs)[i]->dictName);
					if(attrib.Length() > 0) {
						if((*defs)[i]->quotes)
							file->WriteFloatString("%s%s\t\"%s\"\n", prefix.c_str(), (*defs)[i]->dictName.c_str(), attrib.c_str());
						else
							file->WriteFloatString("%s%s\t%s\n", prefix.c_str(), (*defs)[i]->dictName.c_str(), attrib.c_str());
					}
				}
				break;
			case MaterialDef::MATERIAL_DEF_TYPE_BOOL:
				{
					if(GetAttributeBool(stage, (*defs)[i]->dictName))
						file->WriteFloatString("%s%s\t\n",prefix.c_str(), (*defs)[i]->dictName.c_str());
				}
				break;
			case MaterialDef::MATERIAL_DEF_TYPE_FLOAT:
				{
					float val = GetAttributeFloat(stage, (*defs)[i]->dictName);
					file->WriteFloatString("%s%s\t%f\n", prefix.c_str(), (*defs)[i]->dictName.c_str(), val);
				}
				break;
			case MaterialDef::MATERIAL_DEF_TYPE_INT:
				{
					int val = GetAttributeInt(stage, (*defs)[i]->dictName);
					file->WriteFloatString("%s%s\t%d\n", prefix.c_str(), (*defs)[i]->dictName.c_str(), val);
				}
				break;
		}
	}
}
Esempio n. 3
0
//-------------------------------------------------------------
VCNResID VCNMeshLoader::LoadMeshElementTextureCoordXML( XMLNodePtr elementNode, VCNCacheType coordType )
{
  XMLNodePtr node = NULL;

  // Fetch the node we need from the element node
  switch( coordType )
  {
  case VT_DIFFUSE_TEX_COORDS:
    elementNode->selectSingleNode( (VCNTChar*)kNodeDiffuseTexCoords, &node );
    break;
  case VT_NORMAL_TEX_COORDS:
    elementNode->selectSingleNode( (VCNTChar*)kNodeNormalTexCoords, &node );
    break;

  default:
    VCN_ASSERT( false && "Trying to load unrecognized coord type!" );
  }

  // If we didn't find it, we don't have it
  if( node == NULL )
    return kInvalidResID;

  // Get the expected size of the array
  VCNUInt size = 0;
  GetAttributeUInt( node, kAttrVertexTexCoordsSize, size );

  // If we don't have any, leave.
  if( size == 0 )
    return kInvalidResID;

  // Create an array to contain all of this (2 floats per position)
  VCNUInt stride = size * kTexCoordFloats;
  VCNFloat* buffer = new VCNFloat[ stride ];

  // Create some tools...
  VCNFloat* ptrFloat = buffer;
  VCNInt safety = 0;

  // Read the XML and fill the array!
  XMLNodeListPtr textureCoords = 0;
  node->selectNodes( (VCNTChar*)kNodeVertexTexCoord, &textureCoords );
  VCNLong textureCoordsLength = 0;
  textureCoords->get_length( &textureCoordsLength );
  VCN_ASSERT( textureCoordsLength == size && "FILE IS CORRUPTED!" );
  for( VCNLong i=0; i<textureCoordsLength; i++ )
  {
    // Get the first one
    XMLNodePtr textureCoordNode = 0;
    textureCoords->get_item( i, &textureCoordNode );

    // Read the U
    GetAttributeFloat( textureCoordNode, kAttrVertexTexCoordU, *ptrFloat );
    ptrFloat++;

    // Read the V
    GetAttributeFloat( textureCoordNode, kAttrVertexTexCoordV, *ptrFloat );
    ptrFloat++;

    // Verify the safety to make sure we're reading in the right order
    GetAttributeInt( textureCoordNode, kAttrVertexTexCoordID, safety );
    VCN_ASSERT( safety==i && "VERTEX AREN'T READ IN ORDER!" );
  }

  // Now give the information to the cache manager 
  // (he'll take care of making this data API specific)
  VCNResID cacheID = VCNRenderCore::GetInstance()->CreateCache( coordType, buffer, stride*sizeof(VCNFloat) );

  // Clear the buffer
  delete [] buffer;

  // Return the cache ID
  return cacheID;
}
Esempio n. 4
0
//-------------------------------------------------------------
/// A lighting array is composed of normals and colors
//-------------------------------------------------------------
VCNResID VCNMeshLoader::LoadMeshElementLightingXML( XMLNodePtr elementNode )
{
  // Fetch the normals from the element node
  XMLNodePtr normals = 0;
  elementNode->selectSingleNode( (VCNTChar*)kNodeVertexNormals, &normals );
  bool hasNormals = (normals != NULL);

  // Fetch the colors from the element node
  XMLNodePtr colors = 0;
  elementNode->selectSingleNode( (VCNTChar*)kNodeVertexColors, &colors );
  bool hasColors = (colors != NULL);

  // Get the expected size of the normals
  VCNUInt normalSize = 0;
  if( hasNormals )
  {
    GetAttributeUInt( normals, kAttrVertexNormalsSize, normalSize );
    if( normalSize == 0 )
      hasNormals = false;
  }

  // Get the expected size of the colors
  VCNUInt colorSize = 0;
  if( hasColors )
  {
    GetAttributeUInt( colors, kAttrVertexColorsSize, colorSize );
    if( colorSize == 0 )
      hasColors = false;
  }

  // If we have neither, then no lighting information at all
  if( !hasColors && !hasNormals )
    return kInvalidResID;

  // If we have both, they MUST be of same size!
  if( hasColors && hasNormals && (normalSize != colorSize) )
  {
    VCN_ASSERT_FAIL( "LIGHTING REJECTED!" );
    return kInvalidResID;
  }

  // Now just retain one of the sizes
  VCNLong size = (VCNLong)(hasNormals?normalSize:colorSize);
  
  // Create an array to contain all of this (6 floats per vertex)
  VCNUInt stride = size * (kNormalFloats+kColorFloats);
  VCNFloat* buffer = new VCNFloat[ stride ];

  // Create some tools...
  VCNFloat* ptrFloat = buffer;
  VCNInt safety = 0;

  // Pick out the nodes of every normal (if we have them)
  XMLNodeListPtr normalElements;
  if( hasNormals )
  {
    normalElements = 0;
    normals->selectNodes( (VCNTChar*)kNodeVertexNormal, &normalElements );
    VCNLong normalElementsLength = 0;
    normalElements->get_length( &normalElementsLength );
    VCN_ASSERT( normalElementsLength == size && "FILE IS CORRUPTED!" );
  }

  // Pick out the nodes of every color (if we have them)
  XMLNodeListPtr colorsElements;
  if( hasColors )
  {
    colorsElements = 0;
    colors->selectNodes( (VCNTChar*)kNodeVertexColor, &colorsElements );
    VCNLong colorElementsLength = 0;
    normalElements->get_length( &colorElementsLength );
    VCN_ASSERT( colorElementsLength == size && "FILE IS CORRUPTED!" );
  }

  // Now read it in!
  for( VCNLong i=0; i<size; i++ )
  {
    // Normals
    if( hasNormals )
    {
      // Get the element's node
      XMLNodePtr normalNode = 0;
      normalElements->get_item( i, &normalNode );

      // Read the X
      GetAttributeFloat( normalNode, kAttrVertexNormalX, *ptrFloat );
      ptrFloat++;

      // Read the Y
      GetAttributeFloat( normalNode, kAttrVertexNormalY, *ptrFloat );
      ptrFloat++;

      // Read the Z
      GetAttributeFloat( normalNode, kAttrVertexNormalZ, *ptrFloat );
      ptrFloat++;

      // Verify the safety to make sure we're reading in the right order
      GetAttributeInt( normalNode, kAttrVertexNormalID, safety );
      VCN_ASSERT( safety==i && "VERTEX AREN'T READ IN ORDER!" );
    }
    else
    {
      // Put three zeros instead
      *ptrFloat = 0.0f;
      ptrFloat++;
      *ptrFloat = 0.0f;
      ptrFloat++;
      *ptrFloat = 0.0f;
      ptrFloat++;
    }

    // Then colors
    if( hasColors )
    {
      // Get the element's node
      XMLNodePtr colorNode = 0;
      colorsElements->get_item( i, &colorNode );

      // Read the X
      GetAttributeFloat( colorNode, kAttrVertexColorR, *ptrFloat );
      ptrFloat++;

      // Read the Y
      GetAttributeFloat( colorNode, kAttrVertexColorG, *ptrFloat );
      ptrFloat++;

      // Read the Z
      GetAttributeFloat( colorNode, kAttrVertexColorB, *ptrFloat );
      ptrFloat++;

      // Verify the safety to make sure we're reading in the right order
      GetAttributeInt( colorNode, kAttrVertexColorID, safety );
      VCN_ASSERT( safety==i && "VERTEX AREN'T READ IN ORDER!" );
    }
    else
    {
      // Put three ones instead (white)
      *ptrFloat = 1.0f;
      ptrFloat++;
      *ptrFloat = 1.0f;
      ptrFloat++;
      *ptrFloat = 1.0f;
      ptrFloat++;
    }
  }

  // Now give the information to the cache manager 
  // (he'll take care of making this data API specific)
  VCNResID cacheID = VCNRenderCore::GetInstance()->CreateCache( VT_LIGHTING, buffer, stride*sizeof(VCNFloat) );

  // Clear the buffer
  delete [] buffer;

  // Return the cache ID
  return cacheID;
}
Esempio n. 5
0
//-------------------------------------------------------------
VCNResID VCNMeshLoader::LoadMeshElementPositionXML( XMLNodePtr elementNode, VCNSphere* bounding, VCNAabb* aabb /*= NULL*/  )
{
  // Fetch the node we need from the element node
  XMLNodePtr node = 0;
  elementNode->selectSingleNode( (VCNTChar*)kNodeVertexPositions, &node );
  VCN_ASSERT( node != NULL && "No positions in mesh!" );

  // Get the expected size of the array
  VCNUInt size = 0;
  GetAttributeUInt( node, kAttrVertexPositionsSize, size );

  // If we don't have any, leave.
  if( size == 0 )
    return kInvalidResID;

  // Create an array to contain all of this (3 floats per position)
  VCNUInt stride = size * kPositionFloats;
  VCNFloat* buffer = new VCNFloat[ stride ];

  // Create some tools...
  VCNFloat* ptrFloat = buffer;
  VCNInt safety = 0;

  // Keep track of the min and max
  VCNFloat minX, maxX;
  VCNFloat minY, maxY;
  VCNFloat minZ, maxZ;
  minX = minY = minZ = kMaxFloat;
  maxX = maxY = maxZ = kMinFloat;

  // Read the XML and fill the array!
  XMLNodeListPtr positions = 0;
  node->selectNodes( (VCNTChar*)kNodeVertexPosition, &positions );
  VCN_ASSERT( positions != 0 && "FILE IS CORRUPTED!" );
  VCNLong positionsLength = 0;
  positions->get_length( &positionsLength );
  VCN_ASSERT( positionsLength == size && "FILE IS CORRUPTED!" );
  for( VCNLong i=0; i<positionsLength; i++ )
  {
    // Get the element's node
    XMLNodePtr positionNode = 0;
    positions->get_item( i, &positionNode );

    // Read the X
    GetAttributeFloat( positionNode, kAttrVertexPositionX, *ptrFloat );
    if( *ptrFloat < minX )
      minX = *ptrFloat;
    if( *ptrFloat > maxX )
      maxX = *ptrFloat;
    ptrFloat++;

    // Read the Y
    GetAttributeFloat( positionNode, kAttrVertexPositionY, *ptrFloat );
    if( *ptrFloat < minY )
      minY = *ptrFloat;
    if( *ptrFloat > maxY )
      maxY = *ptrFloat;
    ptrFloat++;

    // Read the Z
    GetAttributeFloat( positionNode, kAttrVertexPositionZ, *ptrFloat );
    if( *ptrFloat < minZ )
      minZ = *ptrFloat;
    if( *ptrFloat > maxZ )
      maxZ = *ptrFloat;
    ptrFloat++;

    // Verify the safety to make sure we're reading in the right order
    GetAttributeInt( positionNode, kAttrVertexPositionID, safety );
    VCN_ASSERT( safety==i && "VERTEX AREN'T READ IN ORDER!" );
  }

  // Now give the information to the cache manager 
  // (he'll take care of making this data API specific)
  VCNResID cacheID = VCNRenderCore::GetInstance()->CreateCache( VT_POSITION, buffer, stride*sizeof(VCNFloat) );

  // Clear the buffer
  delete [] buffer;

  Vector3 minVect ( minX, minY, minZ );
  Vector3 maxVect ( maxX, maxY, maxZ );
  Vector3 diagonal = (maxVect - minVect) / 2.0f;
  // If he wants us to fill the AABB, we'll do it for him
  if( bounding )
  {
    VCNSphere tmpSphere( diagonal.Length(), minVect + diagonal );
    *bounding = tmpSphere;
  }
  if (aabb)
  {
	  VCNAabb tempAabb(minVect, maxVect);
	  *aabb = tempAabb;
  }

  // Return the cache ID
  return cacheID;
}
Esempio n. 6
0
int
do_Q_request(ReliSock *syscall_sock,bool &may_fork)
{
	int	request_num = -1;
	int	rval;

	syscall_sock->decode();

	assert( syscall_sock->code(request_num) );

	dprintf(D_SYSCALLS, "Got request #%d\n", request_num);

	switch( request_num ) {

	case CONDOR_InitializeConnection:
	{
		// dprintf( D_ALWAYS, "InitializeConnection()\n" );
		bool authenticated = true;

		// Authenticate socket, if not already done by daemonCore
		if( !syscall_sock->triedAuthentication() ) {
			if( IsDebugLevel(D_SECURITY) ) {
				MyString methods;
				SecMan::getAuthenticationMethods( WRITE, &methods );
				dprintf(D_SECURITY,"Calling authenticate(%s) in qmgmt_receivers\n", methods.Value());
			}
			CondorError errstack;
			if( ! SecMan::authenticate_sock(syscall_sock, WRITE, &errstack) ) {
					// Failed to authenticate
				dprintf( D_ALWAYS, "SCHEDD: authentication failed: %s\n",
						 errstack.getFullText().c_str() );
				authenticated = false;
			}
		}

		if ( authenticated ) {
			InitializeConnection( syscall_sock->getOwner(),
					syscall_sock->getDomain() );
		} else {
			InitializeConnection( NULL, NULL );
		}
		return 0;
	}

	case CONDOR_InitializeReadOnlyConnection:
	{
		// dprintf( D_ALWAYS, "InitializeReadOnlyConnection()\n" );

		// Since InitializeConnection() does nothing, and we need
		// to record the fact that this is a read-only connection,
		// but we have to do it in the socket (since we don't have
		// any other persistent data structure, and it's probably
		// the right place anyway), set the FQU.
		//
		// We need to record if this is a read-only connection so that
		// we can avoid expanding $$ in GetJobAd; simply checking if the
		// connection is authenticated isn't sufficient, because the
		// security session cache means that read-only connection could
		// be authenticated by a previous authenticated connection from
		// the same address (when using host-based security) less than
		// the expiration period ago.
		syscall_sock->setFullyQualifiedUser( "read-only" );

		// same as InitializeConnection but no authenticate()
		InitializeConnection( NULL, NULL );

		may_fork = true;
		return 0;
	}

	case CONDOR_SetEffectiveOwner:
	{
		MyString owner;
		int terrno;

		assert( syscall_sock->get(owner) );
		assert( syscall_sock->end_of_message() );

		rval = QmgmtSetEffectiveOwner( owner.Value() );
		terrno = errno;

		syscall_sock->encode();
		assert( syscall_sock->code(rval) );
		if( rval < 0 ) {
			assert( syscall_sock->code(terrno) );
		}
		assert( syscall_sock->end_of_message() );

		char const *fqu = syscall_sock->getFullyQualifiedUser();
		dprintf(D_SYSCALLS, "\tSetEffectiveOwner\n");
		dprintf(D_SYSCALLS, "\tauthenticated user = '******'\n", fqu ? fqu : "");
		dprintf(D_SYSCALLS, "\trequested owner = '%s'\n", owner.Value());
		dprintf(D_SYSCALLS, "\trval %d, errno %d\n", rval, terrno);

		return 0;
	}

	case CONDOR_NewCluster:
	  {
		int terrno;

		assert( syscall_sock->end_of_message() );;

		errno = 0;
		rval = NewCluster( );
		terrno = errno;
		dprintf(D_SYSCALLS, 
				"\tNewCluster: rval = %d, errno = %d\n",rval,terrno );
		if ( rval > 0 ) {
			dprintf( D_AUDIT, *syscall_sock, 
					 "Submitting new job %d.0\n", rval );
		}

		syscall_sock->encode();
		assert( syscall_sock->code(rval) );
		if( rval < 0 ) {
			assert( syscall_sock->code(terrno) );
		}
		assert( syscall_sock->end_of_message() );;

		dprintf(D_FULLDEBUG,"schedd: NewCluster rval %d errno %d\n",rval,terrno);

		return 0;
	}

	case CONDOR_NewProc:
	  {
		int cluster_id = -1;
		int terrno;

		assert( syscall_sock->code(cluster_id) );
		dprintf( D_SYSCALLS, "	cluster_id = %d\n", cluster_id );
		assert( syscall_sock->end_of_message() );;

		errno = 0;
		rval = NewProc( cluster_id );
		terrno = errno;
		dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );
		if ( rval > 0 ) {
			dprintf( D_AUDIT, *syscall_sock, 
					 "Submitting new job %d.%d\n", cluster_id, rval );
		}

		syscall_sock->encode();
		assert( syscall_sock->code(rval) );
		if( rval < 0 ) {
			assert( syscall_sock->code(terrno) );
		}
		assert( syscall_sock->end_of_message() );;

		dprintf(D_FULLDEBUG,"schedd: NewProc rval %d errno %d\n",rval,terrno);

		return 0;
	}

	case CONDOR_DestroyProc:
	  {
		int cluster_id = -1;
		int proc_id = -1;
		int terrno;

		assert( syscall_sock->code(cluster_id) );
		dprintf( D_SYSCALLS, "	cluster_id = %d\n", cluster_id );
		assert( syscall_sock->code(proc_id) );
		dprintf( D_SYSCALLS, "	proc_id = %d\n", proc_id );
		assert( syscall_sock->end_of_message() );;

		errno = 0;
		rval = DestroyProc( cluster_id, proc_id );
		terrno = errno;
		dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );

		syscall_sock->encode();
		assert( syscall_sock->code(rval) );
		if( rval < 0 ) {
			assert( syscall_sock->code(terrno) );
		}
		assert( syscall_sock->end_of_message() );;

		dprintf(D_FULLDEBUG,"schedd: DestroyProc cluster %d proc %d rval %d errno %d\n",cluster_id,proc_id,rval,terrno);

		return 0;
	}

	case CONDOR_DestroyCluster:
	  {
		int cluster_id = -1;
		int terrno;

		assert( syscall_sock->code(cluster_id) );
		dprintf( D_SYSCALLS, "	cluster_id = %d\n", cluster_id );
		assert( syscall_sock->end_of_message() );;

		errno = 0;
		rval = DestroyCluster( cluster_id );
		terrno = errno;
		dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );

		syscall_sock->encode();
		assert( syscall_sock->code(rval) );
		if( rval < 0 ) {
			assert( syscall_sock->code(terrno) );
		}
		assert( syscall_sock->end_of_message() );;
		return 0;
	}

#if 0
	case CONDOR_DestroyClusterByConstraint:
	  {
		char *constraint=NULL;
		int terrno;

		assert( syscall_sock->code(constraint) );
		assert( syscall_sock->end_of_message() );;

		errno = 0;
		rval = DestroyClusterByConstraint( constraint );
		terrno = errno;
		dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );

		syscall_sock->encode();
		assert( syscall_sock->code(rval) );
		if( rval < 0 ) {
			assert( syscall_sock->code(terrno) );
		}
		free( (char *)constraint );
		assert( syscall_sock->end_of_message() );;
		return 0;
	}
#endif

	case CONDOR_SetAttributeByConstraint:
	case CONDOR_SetAttributeByConstraint2:
	  {
		char *attr_name=NULL;
		char *attr_value=NULL;
		char *constraint=NULL;
		int terrno;
		SetAttributeFlags_t flags = 0;

		assert( syscall_sock->code(constraint) );
		dprintf( D_SYSCALLS, "  constraint = %s\n",constraint);
		assert( syscall_sock->code(attr_value) );
		assert( syscall_sock->code(attr_name) );
		if( request_num == CONDOR_SetAttributeByConstraint2 ) {
			assert( syscall_sock->code( flags ) );
		}
		assert( syscall_sock->end_of_message() );;

		if (strcmp (attr_name, ATTR_MYPROXY_PASSWORD) == 0) {
			errno = 0;
			dprintf( D_SYSCALLS, "SetAttributeByConstraint (MyProxyPassword) not supported...\n");
			rval = 0;
			terrno = errno;
		} else {

			errno = 0;
			rval = SetAttributeByConstraint( constraint, attr_name, attr_value, flags );
			terrno = errno;
			dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );
			if ( rval == 0 ) {
				dprintf( D_AUDIT, *syscall_sock,
						 "Set Attribute By Constraint %s, "
						 "%s = %s\n",
						 constraint, attr_name, attr_value);
			}

		}

		syscall_sock->encode();
		assert( syscall_sock->code(rval) );
		if( rval < 0 ) {
			assert( syscall_sock->code(terrno) );
		}
		free( (char *)constraint );
		free( (char *)attr_value );
		free( (char *)attr_name );
		assert( syscall_sock->end_of_message() );;
		return 0;
	}

	case CONDOR_SetAttribute:
	case CONDOR_SetAttribute2:
	  {
		int cluster_id = -1;
		int proc_id = -1;
		char *attr_name=NULL;
		char *attr_value=NULL;
		int terrno;
		SetAttributeFlags_t flags = 0;
		const char *users_username;
		const char *condor_username;

		assert( syscall_sock->code(cluster_id) );
		dprintf( D_SYSCALLS, "	cluster_id = %d\n", cluster_id );
		assert( syscall_sock->code(proc_id) );
		dprintf( D_SYSCALLS, "	proc_id = %d\n", proc_id );
		assert( syscall_sock->code(attr_value) );
		assert( syscall_sock->code(attr_name) );
		if( request_num == CONDOR_SetAttribute2 ) {
			assert( syscall_sock->code( flags ) );
		}
		users_username = syscall_sock->getOwner();
		condor_username = get_condor_username();
		if (attr_name) dprintf(D_SYSCALLS,"\tattr_name = %s\n",attr_name);
		if (attr_value) dprintf(D_SYSCALLS,"\tattr_value = %s\n",attr_value);		
		assert( syscall_sock->end_of_message() );;

		// ckireyev:
		// We do NOT want to include MyProxy password in the ClassAd (since it's a secret)
		// I'm not sure if this is the best place to do this, but....
		if (attr_name && attr_value && strcmp (attr_name, ATTR_MYPROXY_PASSWORD) == 0) {
			errno = 0;
			dprintf( D_SYSCALLS, "Got MyProxyPassword, stashing...\n");
			rval = SetMyProxyPassword (cluster_id, proc_id, attr_value);
			terrno = errno;
			dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );
			
		}
		else {
			errno = 0;

			rval = SetAttribute( cluster_id, proc_id, attr_name, attr_value, flags );
			terrno = errno;
			dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );
				// If we're modifying a previously-submitted job AND either
				// the client's username is not HTCondor's (i.e. not a
				// daemon) OR the client says we should log...
			if( (cluster_id != active_cluster_num) && (rval == 0) &&
				( strcmp(users_username, condor_username) || (flags & SHOULDLOG) ) ) { 

				dprintf( D_AUDIT, *syscall_sock, 
						 "Set Attribute for job %d.%d, "
						 "%s = %s\n",
						 cluster_id, proc_id, attr_name, attr_value);
			}
		}

		free( (char *)attr_value );
		free( (char *)attr_name );

		if( flags & SetAttribute_NoAck ) {
			if( rval < 0 ) {
				return -1;
			}
		}
		else {
			syscall_sock->encode();
			assert( syscall_sock->code(rval) );
			if( rval < 0 ) {
				assert( syscall_sock->code(terrno) );
			}
			assert( syscall_sock->end_of_message() );
		}
		return 0;
	}

	case CONDOR_SetTimerAttribute:
	  {
		int cluster_id = -1;
		int proc_id = -1;
		char *attr_name=NULL;
		int duration = 0;
		int terrno;

		assert( syscall_sock->code(cluster_id) );
		dprintf( D_SYSCALLS, "	cluster_id = %d\n", cluster_id );
		assert( syscall_sock->code(proc_id) );
		dprintf( D_SYSCALLS, "	proc_id = %d\n", proc_id );
		assert( syscall_sock->code(attr_name) );
		if (attr_name) dprintf(D_SYSCALLS,"\tattr_name = %s\n",attr_name);
		assert( syscall_sock->code(duration) );
		dprintf(D_SYSCALLS,"\tduration = %d\n",duration);
		assert( syscall_sock->end_of_message() );;

		errno = 0;

		rval = SetTimerAttribute( cluster_id, proc_id, attr_name, duration );
		terrno = errno;
		dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );
		dprintf( D_AUDIT, *syscall_sock, 
				 "Set Timer Attribute for job %d.%d, "
				 "attr_name = %s, duration = %d\n",
				 cluster_id, proc_id, attr_name, duration);

		syscall_sock->encode();
		assert( syscall_sock->code(rval) );
		if( rval < 0 ) {
			assert( syscall_sock->code(terrno) );
		}
		free( (char *)attr_name );
		assert( syscall_sock->end_of_message() );;
		return 0;
	}

	case CONDOR_BeginTransaction:
	  {
		int terrno;

		assert( syscall_sock->end_of_message() );;

		errno = 0;
		rval = 0;	// BeginTransaction returns void (sigh), so always success
		BeginTransaction( );
		terrno = errno;
		dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );

		syscall_sock->encode();
		assert( syscall_sock->code(rval) );
		if( rval < 0 ) {
			assert( syscall_sock->code(terrno) );
		}
		assert( syscall_sock->end_of_message() );;
		return 0;
	}

	case CONDOR_AbortTransaction:
	{
		int terrno;

		assert( syscall_sock->end_of_message() );;

		errno = 0;
		rval = 0;	// AbortTransaction returns void (sigh), so always success

		AbortTransaction( );
		terrno = errno;
		dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );


		syscall_sock->encode();
		assert( syscall_sock->code(rval) );
		if( rval < 0 ) {
			assert( syscall_sock->code(terrno) );
		}

		assert( syscall_sock->end_of_message() );;
		return 0;
	}

	case CONDOR_CommitTransactionNoFlags:
	case CONDOR_CommitTransaction:
	  {
		int terrno;
		int flags;

		if( request_num == CONDOR_CommitTransaction ) {
			assert( syscall_sock->code(flags) );
		}
		else {
			flags = 0;
		}
		assert( syscall_sock->end_of_message() );;

		errno = 0;
		CondorError errstack;
		rval = CheckTransaction( flags, & errstack );
		terrno = errno;
		dprintf( D_SYSCALLS, "\tflags = %d, rval = %d, errno = %d\n", flags, rval, terrno );

		if( rval >= 0 ) {
			errno = 0;
			CommitTransaction( flags );
				// CommitTransaction() never returns on failure
			rval = 0;
			terrno = errno;
			dprintf( D_SYSCALLS, "\tflags = %d, rval = %d, errno = %d\n", flags, rval, terrno );
		}

		syscall_sock->encode();
		assert( syscall_sock->code(rval) );
		if( rval < 0 ) {
			assert( syscall_sock->code(terrno) );
			const CondorVersionInfo *vers = syscall_sock->get_peer_version();
			if (vers && vers->built_since_version(8, 3, 4))
			{
				// Send a classad, for less backwards-incompatibility.
				int code = 1;
				const char * reason = "QMGMT rejected job submission.";
				if( errstack.subsys() ) {
					code = 2;
					reason = errstack.message();
				}

				ClassAd reply;
				reply.Assign( "ErrorCode", code );
				reply.Assign( "ErrorReason", reason );
				assert( putClassAd( syscall_sock, reply ) );
			}
		}
		assert( syscall_sock->end_of_message() );;
		return 0;
	}

	case CONDOR_GetAttributeFloat:
	  {
		int cluster_id = -1;
		int proc_id = -1;
		char *attr_name=NULL;
		float value = 0.0;
		int terrno;

		assert( syscall_sock->code(cluster_id) );
		dprintf( D_SYSCALLS, "	cluster_id = %d\n", cluster_id );
		assert( syscall_sock->code(proc_id) );
		dprintf( D_SYSCALLS, "	proc_id = %d\n", proc_id );
		assert( syscall_sock->code(attr_name) );
		assert( syscall_sock->end_of_message() );;

		errno = 0;
		if( QmgmtMayAccessAttribute( attr_name ) ) {
			rval = GetAttributeFloat( cluster_id, proc_id, attr_name, &value );
		}
		else {
			rval = -1;
		}
		terrno = errno;
		dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );

		syscall_sock->encode();
		assert( syscall_sock->code(rval) );
		if( rval < 0 ) {
			assert( syscall_sock->code(terrno) );
		}
		if( rval >= 0 ) {
			assert( syscall_sock->code(value) );
		}
		free( (char *)attr_name );
		assert( syscall_sock->end_of_message() );;
		return 0;
	}

	case CONDOR_GetAttributeInt:
	  {
		int cluster_id = -1;
		int proc_id = -1;
		char *attr_name=NULL;
		int value = 0;
		int terrno;

		assert( syscall_sock->code(cluster_id) );
		dprintf( D_SYSCALLS, "	cluster_id = %d\n", cluster_id );
		assert( syscall_sock->code(proc_id) );
		dprintf( D_SYSCALLS, "	proc_id = %d\n", proc_id );
		assert( syscall_sock->code(attr_name) );
		dprintf( D_SYSCALLS, "  attr_name = %s\n", attr_name );
		assert( syscall_sock->end_of_message() );;

		errno = 0;
		if( QmgmtMayAccessAttribute( attr_name ) ) {
			rval = GetAttributeInt( cluster_id, proc_id, attr_name, &value );
		}
		else {
			rval = -1;
		}
		terrno = errno;
		if (rval < 0) {
			dprintf( D_SYSCALLS, "GetAttributeInt(%d, %d, %s) not found.\n",
					cluster_id, proc_id, attr_name);
		} else {
			dprintf( D_SYSCALLS, "  value: %d\n", value );
			dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );
		}

		syscall_sock->encode();
		assert( syscall_sock->code(rval) );
		if( rval < 0 ) {
			assert( syscall_sock->code(terrno) );
		}
		if( rval >= 0 ) {
			assert( syscall_sock->code(value) );
		}
		free( (char *)attr_name );
		assert( syscall_sock->end_of_message() );;
		return 0;
	}

	case CONDOR_GetAttributeString:
	  {
		int cluster_id = -1;
		int proc_id = -1;
		char *attr_name=NULL;
		char *value = NULL;
		int terrno;

		assert( syscall_sock->code(cluster_id) );
		dprintf( D_SYSCALLS, "	cluster_id = %d\n", cluster_id );
		assert( syscall_sock->code(proc_id) );
		dprintf( D_SYSCALLS, "	proc_id = %d\n", proc_id );
		assert( syscall_sock->code(attr_name) );
		assert( syscall_sock->end_of_message() );;

		errno = 0;
		if( QmgmtMayAccessAttribute( attr_name ) ) {
			rval = GetAttributeStringNew( cluster_id, proc_id, attr_name, &value );
		}
		else {
			rval = -1;
		}
		terrno = errno;
		dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );

		syscall_sock->encode();
		assert( syscall_sock->code(rval) );
		if( rval < 0 ) {
			assert( syscall_sock->code(terrno) );
		}
		if( rval >= 0 ) {
			assert( syscall_sock->code(value) );
		}
		free( (char *)value );
		free( (char *)attr_name );
		assert( syscall_sock->end_of_message() );;
		return 0;
	}

	case CONDOR_GetAttributeExpr:
	  {
		int cluster_id = -1;
		int proc_id = -1;
		char *attr_name=NULL;

		int terrno;

		assert( syscall_sock->code(cluster_id) );
		dprintf( D_SYSCALLS, "	cluster_id = %d\n", cluster_id );
		assert( syscall_sock->code(proc_id) );
		dprintf( D_SYSCALLS, "	proc_id = %d\n", proc_id );
		assert( syscall_sock->code(attr_name) );
		assert( syscall_sock->end_of_message() );;

		char *value = NULL;

		errno = 0;
		if( QmgmtMayAccessAttribute( attr_name ) ) {
			rval = GetAttributeExprNew( cluster_id, proc_id, attr_name, &value );
		}
		else {
			rval = -1;
		}
		terrno = errno;
		dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );

		syscall_sock->encode();

		if ( !syscall_sock->code(rval) ) {
			free(value);
			return -1;
		}
		if( rval < 0 ) {
			if ( !syscall_sock->code(terrno) ) {
					free(value);
					return -1;
			}
		}
		if( rval >= 0 ) {
			if ( !syscall_sock->code(value) ) {
					free(value);
					return -1;
			}
		}
		free( (char *)value );
		free( (char *)attr_name );
		assert( syscall_sock->end_of_message() );;
		return 0;
	}

	case CONDOR_GetDirtyAttributes:
	  {
		int cluster_id = -1;
		int proc_id = -1;
		ClassAd updates;

		int terrno;

		assert( syscall_sock->code(cluster_id) );
		dprintf( D_SYSCALLS, "	cluster_id = %d\n", cluster_id );
		assert( syscall_sock->code(proc_id) );
		dprintf( D_SYSCALLS, "	proc_id = %d\n", proc_id );
		assert( syscall_sock->end_of_message() );;

		errno = 0;
		rval = GetDirtyAttributes( cluster_id, proc_id, &updates );

		terrno = errno;
		dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );

		syscall_sock->encode();

		if ( !syscall_sock->code(rval) ) {
			return -1;
		}
		if( rval < 0 ) {
			if ( !syscall_sock->code(terrno) ) {
					return -1;
			}
		}
		if( rval >= 0 ) {
			assert( putClassAd(syscall_sock, updates) );
		}
		assert( syscall_sock->end_of_message() );;
		return 0;
	}

	case CONDOR_DeleteAttribute:
	  {
		int cluster_id = -1;
		int proc_id = -1;
		char *attr_name=NULL;
		int terrno;

		assert( syscall_sock->code(cluster_id) );
		dprintf( D_SYSCALLS, "	cluster_id = %d\n", cluster_id );
		assert( syscall_sock->code(proc_id) );
		dprintf( D_SYSCALLS, "	proc_id = %d\n", proc_id );
		assert( syscall_sock->code(attr_name) );
		assert( syscall_sock->end_of_message() );;

		errno = 0;
		rval = DeleteAttribute( cluster_id, proc_id, attr_name );
		terrno = errno;
		dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );

		syscall_sock->encode();
		assert( syscall_sock->code(rval) );
		if( rval < 0 ) {
			assert( syscall_sock->code(terrno) );
		}
		free( (char *)attr_name );
		assert( syscall_sock->end_of_message() );;
		return 0;
	}

	case CONDOR_GetJobAd:
	  {
		int cluster_id = -1;
		int proc_id = -1;
		ClassAd *ad = NULL;
		int terrno;
		bool delete_ad = false;

		assert( syscall_sock->code(cluster_id) );
		dprintf( D_SYSCALLS, "	cluster_id = %d\n", cluster_id );
		assert( syscall_sock->code(proc_id) );
		dprintf( D_SYSCALLS, "	proc_id = %d\n", proc_id );
		assert( syscall_sock->end_of_message() );;

		// dprintf( D_ALWAYS, "(%d.%d) isAuthenticated() = %d\n", cluster_id, proc_id, syscall_sock->isAuthenticated() );
		// dprintf( D_ALWAYS, "(%d.%d) getOwner() = %s\n", cluster_id, proc_id, syscall_sock->getOwner() );

		errno = 0;
		// Only fetch the jobad for legal values of cluster/proc
		if( cluster_id >= 1 ) {
			if( proc_id >= 0 ) {
				const char * fqu = syscall_sock->getFullyQualifiedUser();
				if( fqu != NULL && strcmp( fqu, "read-only" ) != 0 ) {
					// expand $$() macros in the jobad as required by GridManager.
					// The GridManager depends on the fact that the following call
					// expands $$ and saves the expansions to disk in case of
					// restart.
					ad = GetJobAd_as_ClassAd( cluster_id, proc_id, true, true );
					delete_ad = true;
					// note : since we expanded the ad, ad is now a deep
					// copy of the ad in memory, so we must delete it below.
				} else {
					ad = GetJobAd_as_ClassAd( cluster_id, proc_id, false, false );
				}
			} else if( proc_id == -1 ) {
				// allow cluster ad to be queried as required by preen, but
				// do NOT ask to expand $$() macros in a cluster ad!
				ad = GetJobAd_as_ClassAd( cluster_id, proc_id, false, false );
			}
		}
		terrno = errno;
		rval = ad ? 0 : -1;
		dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );

		syscall_sock->encode();
		assert( syscall_sock->code(rval) );
		if( rval < 0 ) {
			assert( syscall_sock->code(terrno) );
		}
		if( rval >= 0 ) {
			assert( putClassAd(syscall_sock, *ad, PUT_CLASSAD_NO_PRIVATE) );
		}
		// If we called GetJobAd() with the third bool argument set
		// to True (expandedAd), it does a deep copy of the ad in the
		// queue in order to expand the $$() attributes.  So we must
		// delete it.
		if (delete_ad) delete ad;
		assert( syscall_sock->end_of_message() );;
		return 0;
	}

	case CONDOR_GetJobByConstraint:
	  {
		char *constraint=NULL;
		ClassAd *ad;
		int terrno;

		assert( syscall_sock->code(constraint) );
		assert( syscall_sock->end_of_message() );;

		errno = 0;
		ad = GetJobByConstraint_as_ClassAd( constraint );
		terrno = errno;
		rval = ad ? 0 : -1;
		dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );

		syscall_sock->encode();
		assert( syscall_sock->code(rval) );
		if( rval < 0 ) {
			assert( syscall_sock->code(terrno) );
		}
		if( rval >= 0 ) {
			assert( putClassAd(syscall_sock, *ad, PUT_CLASSAD_NO_PRIVATE) );
		}
		FreeJobAd(ad);
		free( (char *)constraint );
		assert( syscall_sock->end_of_message() );;
		return 0;
	}

	case CONDOR_GetNextJob:
	  {
		ClassAd *ad;
		int initScan = 0;
		int terrno;

		assert( syscall_sock->code(initScan) );
		dprintf( D_SYSCALLS, "	initScan = %d\n", initScan );
		assert( syscall_sock->end_of_message() );;

		errno = 0;
		ad = GetNextJob( initScan );
		terrno = errno;
		rval = ad ? 0 : -1;
		dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );

		syscall_sock->encode();
		assert( syscall_sock->code(rval) );
		if( rval < 0 ) {
			assert( syscall_sock->code(terrno) );
		}
		if( rval >= 0 ) {
			assert( putClassAd(syscall_sock, *ad, PUT_CLASSAD_NO_PRIVATE) );
		}
		FreeJobAd(ad);
		assert( syscall_sock->end_of_message() );;
		return 0;
	}

	case CONDOR_GetNextJobByConstraint:
	  {
		char *constraint=NULL;
		ClassAd *ad;
		int initScan = 0;
		int terrno;

		assert( syscall_sock->code(initScan) );
		dprintf( D_SYSCALLS, "	initScan = %d\n", initScan );
		if ( !(syscall_sock->code(constraint)) ) {
			if (constraint != NULL) {
				free(constraint);
				constraint = NULL;
			}
			return -1;
		}
		assert( syscall_sock->end_of_message() );;

		errno = 0;
		ad = GetNextJobByConstraint( constraint, initScan );
		terrno = errno;
		rval = ad ? 0 : -1;
		dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );

		syscall_sock->encode();
		assert( syscall_sock->code(rval) );
		if( rval < 0 ) {
			assert( syscall_sock->code(terrno) );
		}
		if( rval >= 0 ) {
			assert( putClassAd(syscall_sock, *ad, PUT_CLASSAD_NO_PRIVATE) );
		}
		FreeJobAd(ad);
		free( (char *)constraint );
		assert( syscall_sock->end_of_message() );;
		return 0;
	}
	case CONDOR_GetNextDirtyJobByConstraint:
	{
		char *constraint=NULL;
		ClassAd *ad;
		int initScan = 0;
		int terrno;

		assert( syscall_sock->code(initScan) );
		dprintf( D_SYSCALLS, "  initScan = %d\n", initScan );
		if ( !(syscall_sock->code(constraint)) ) {
			if (constraint != NULL) {
				free(constraint);
				constraint = NULL;
			}
			return -1;
		}
		assert( syscall_sock->end_of_message() );

		errno = 0;
		ad = GetNextDirtyJobByConstraint( constraint, initScan );
		terrno = errno;
		rval = ad ? 0 : -1;
		dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );

		syscall_sock->encode();
		assert( syscall_sock->code(rval) );
		if( rval < 0 ) {
			assert( syscall_sock->code(terrno) );
		}
		if( rval >= 0 ) {
			assert( putClassAd(syscall_sock, *ad, PUT_CLASSAD_NO_PRIVATE) );
		}
		FreeJobAd(ad);
		free( (char *)constraint );
		assert( syscall_sock->end_of_message() );
		return 0;
	}

	case CONDOR_SendSpoolFile:
	  {
		char *filename=NULL;
		int terrno;

		assert( syscall_sock->code(filename) );
		assert( syscall_sock->end_of_message() );;

		errno = 0;
		rval = SendSpoolFile( filename );
		terrno = errno;
		dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );
#if 0
		syscall_sock->encode();
		assert( syscall_sock->code(rval) );
		if( rval < 0 ) {
			assert( syscall_sock->code(terrno) );
		}
		assert( syscall_sock->end_of_message() );;
#endif
		free( (char *)filename );
		return 0;
	}

	case CONDOR_SendSpoolFileIfNeeded:
	  {
		int terrno;

		ClassAd ad;
		assert( getClassAd(syscall_sock, ad) );
		assert( syscall_sock->end_of_message() );;

		errno = 0;
		rval = SendSpoolFileIfNeeded(ad);
		terrno = errno;
		dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );

		return 0;
	}

	case CONDOR_GetAllJobsByConstraint:
	  {
		char *constraint=NULL;
		char *projection=NULL;
		ClassAd *ad;
		int terrno;
		int initScan = 1;
		classad::References proj;

		if ( !(syscall_sock->code(constraint)) ) {
			if (constraint != NULL) {
				free(constraint);
				constraint = NULL;
			}
			return -1;
		}
		if ( !(syscall_sock->code(projection)) ) {
			if (projection != NULL) {
				free(constraint);
				free(projection);
				projection = NULL;
			}
			return -1;
		}
		dprintf( D_SYSCALLS, "	constraint = %s\n", constraint );
		dprintf( D_SYSCALLS, "	projection = %s\n", projection ? projection : "");

		assert( syscall_sock->end_of_message() );;

		// if there is a projection, convert it into a set of attribute names
		if (projection) {
			StringTokenIterator list(projection);
			const std::string * attr;
			while ((attr = list.next_string())) { proj.insert(*attr); }
		}

		syscall_sock->encode();

		do {
			errno = 0;

			ad = GetNextJobByConstraint( constraint, initScan );
			initScan=0; // one first time through, otherwise 0

			terrno = errno;
			rval = ad ? 0 : -1;
			dprintf( D_SYSCALLS, "\trval = %d, errno = %d\n", rval, terrno );

			assert( syscall_sock->code(rval) );

			if( rval < 0 ) {
				assert( syscall_sock->code(terrno) );
			}

			if( rval >= 0 ) {
				assert( putClassAd(syscall_sock, *ad, PUT_CLASSAD_NO_PRIVATE, proj.empty() ? NULL : &proj) );
				FreeJobAd(ad);
			}
		} while (rval >= 0);
		assert( syscall_sock->end_of_message() );;

		free( (char *)constraint );
		free( (char *)projection );
		return 0; 
	}

	case CONDOR_CloseSocket:
	{
		assert( syscall_sock->end_of_message() );;
		return -1;
	}

	} /* End of switch */

	return -1;
} /* End of function */
Esempio n. 7
0
//-------------------------------------------------------------
VCNAnimJoint* VCNAnimLoader::LoadJointXML( XMLNodePtr jointNode )
{
	VCNAnimJoint* animJoint = new VCNAnimJoint();

	// Read the name of the target for the joint and store it
	VCNString tmpString;
	if( GetAttributeString(jointNode, kAttrAnimJointTarget, tmpString) )
	{
		animJoint->SetTargetName( tmpString );
	}

	// Temp variables for lecture
	VCNFloat fTime;
	Vector3 tmpVector;
	VCNQuat tmpQuat;
	VCNUInt count;
	VCNBool readSuccess;

	// Get the number of rotation frames
	GetAttributeUInt(jointNode, kAttrAnimJointPosCount, count);

	// Lets load up all the positions!
	XMLNodeListPtr posNodes;
	jointNode->selectNodes( (VCNTChar*)kNodeAnimJointPosition, &posNodes );
	VCNLong posNodeCount;
	posNodes->get_length( &posNodeCount );
	VCN_ASSERT( (long)count == posNodeCount );
	for( VCNLong i=0; i<posNodeCount; i++ )
	{
		// Get the mesh's node
		XMLNodePtr posNode;
		posNodes->get_item( i, &posNode );

		// Get the frame time for this position
		GetAttributeFloat(posNode, kAttrAnimJointPosFrameTime, fTime);

		// Get the x position
		GetAttributeFloat(posNode, kAttrAnimJointFramePosX, tmpVector.x);

		// Get the y position
		GetAttributeFloat(posNode, kAttrAnimJointFramePosY, tmpVector.y);

		// Get the z position
		GetAttributeFloat(posNode, kAttrAnimJointFramePosZ, tmpVector.z);

		// Add it to the joint
		animJoint->AddPosFrame( fTime, tmpVector );
	}

	// Get the number of rotation frames
	GetAttributeUInt(jointNode, kAttrAnimJointRotCount, count);

	// Lets load up all the rotations!
	XMLNodeListPtr rotNodes;
	jointNode->selectNodes( (VCNTChar*)kNodeAnimJointRotation, &rotNodes );
	VCNLong rotNodeCount;
	rotNodes->get_length( &rotNodeCount );
	VCN_ASSERT( (long)count == rotNodeCount );
	for( VCNLong i=0; i<rotNodeCount; i++ )
	{
		// Get the mesh's node
		XMLNodePtr rotNode;
		rotNodes->get_item( i, &rotNode );

		// Get the frame time for this position
		readSuccess = GetAttributeFloat(rotNode, kAttrAnimJointPosFrameTime, fTime);
		VCN_ASSERT(readSuccess);

		// Get the x of the quat
		readSuccess = GetAttributeFloat(rotNode, kAttrAnimJointFrameRotX, tmpQuat.x);
		VCN_ASSERT(readSuccess);

		// Get the y of the quat
		readSuccess = GetAttributeFloat(rotNode, kAttrAnimJointFrameRotY, tmpQuat.y);
		VCN_ASSERT(readSuccess);

		// Get the z of the quat
		readSuccess = GetAttributeFloat(rotNode, kAttrAnimJointFrameRotZ, tmpQuat.z);
		VCN_ASSERT(readSuccess);

		// Get the w of the quat
		readSuccess = GetAttributeFloat(rotNode, kAttrAnimJointFrameRotW, tmpQuat.w);
		VCN_ASSERT(readSuccess);

		// Add it to the joint
		animJoint->AddRotFrame( fTime, tmpQuat );
	}

	// Get the number of scale frames
	GetAttributeUInt(jointNode, kAttrAnimJointScaleCount, count);


	// Lets load up all the scales!
	XMLNodeListPtr scaleNodes;
	jointNode->selectNodes( (VCNTChar*)kNodeAnimJointScale, &scaleNodes );
	VCNLong scaleNodeCount;
	scaleNodes->get_length( &scaleNodeCount );
	VCN_ASSERT( (long)count == scaleNodeCount );
	for( VCNLong i=0; i<scaleNodeCount; i++ )
	{
		// Get the mesh's node
		XMLNodePtr scaleNode;
		scaleNodes->get_item( i, &scaleNode );

		// Get the frame time for this position
		readSuccess = GetAttributeFloat(scaleNode, kAttrAnimJointScaleFrameTime, fTime);
		VCN_ASSERT(readSuccess);

		// Get the x of the quat
		readSuccess = GetAttributeFloat(scaleNode, kAttrAnimJointFrameScaleX, tmpVector.x);
		VCN_ASSERT(readSuccess);

		// Get the y of the quat
		readSuccess = GetAttributeFloat(scaleNode, kAttrAnimJointFrameScaleY, tmpVector.y);
		VCN_ASSERT(readSuccess);

		// Get the z of the quat
		readSuccess = GetAttributeFloat(scaleNode, kAttrAnimJointFrameScaleZ, tmpVector.z);
		VCN_ASSERT(readSuccess);

		// Add it to the joint
		animJoint->AddScaleFrame( fTime, tmpVector );
	}

	// Return the joint
	return animJoint;
}