Ejemplo n.º 1
0
int
rsOpenCollection (rsComm_t *rsComm, collInp_t *openCollInp)
{
    int status;
    int handleInx;
    collHandle_t *collHandle;
    rodsObjStat_t *rodsObjStatOut = NULL;

    handleInx = allocCollHandle ();

    if (handleInx < 0) return (handleInx);

    collHandle = &CollHandle[handleInx];

    status = rsInitQueryHandle (&collHandle->queryHandle, rsComm);
   
    if (status < 0) return status;

    rstrcpy (collHandle->dataObjInp.objPath, openCollInp->collName, 
      MAX_NAME_LEN);
    if ((openCollInp->flags & INCLUDE_CONDINPUT_IN_QUERY) != 0) {
	replKeyVal (&openCollInp->condInput, &collHandle->dataObjInp.condInput);
    }
    status = rsObjStat (rsComm, &collHandle->dataObjInp, &rodsObjStatOut);


    if (status < 0) {
	rsCloseCollection (rsComm, &handleInx);
	return status;
    }

    if (rodsObjStatOut->objType != COLL_OBJ_T) {
	freeRodsObjStat (rodsObjStatOut);
	rsCloseCollection (rsComm, &handleInx);
	return CAT_NAME_EXISTS_AS_DATAOBJ;
    }

#if 0
    collHandle->dataObjInp.specColl = rodsObjStatOut->specColl;
#else
    replSpecColl (rodsObjStatOut->specColl, &collHandle->dataObjInp.specColl);
#endif
    if (rodsObjStatOut->specColl != NULL &&
      rodsObjStatOut->specColl->collClass == LINKED_COLL) {
	/* save the linked path */
	rstrcpy (collHandle->linkedObjPath, rodsObjStatOut->specColl->objPath,
	  MAX_NAME_LEN);
    };

    collHandle->rodsObjStat = rodsObjStatOut;

    collHandle->state = COLL_OPENED;
    collHandle->flags = openCollInp->flags;
    /* the collection exist. now query the data in it */
    return (handleInx);
}
Ejemplo n.º 2
0
int
rsRegColl (rsComm_t *rsComm, collInp_t *regCollInp)
{
    int status;
    rodsServerHost_t *rodsServerHost = NULL;
    dataObjInp_t dataObjInp;
    rodsObjStat_t *rodsObjStatOut = NULL;


    memset (&dataObjInp, 0, sizeof (dataObjInp));

    rstrcpy (dataObjInp.objPath, regCollInp->collName, MAX_NAME_LEN);
#if 0   /* separate specColl */
    status = __rsObjStat (rsComm, &dataObjInp, 1, &rodsObjStatOut);
#endif
    status = rsObjStat (rsComm, &dataObjInp, &rodsObjStatOut);
    if (status >= 0) {
        if (rodsObjStatOut != NULL && rodsObjStatOut->specColl != NULL) {	// cppcheck - Possible null pointer dereference: rodsObjStatOut
            rodsLog (LOG_ERROR,
             "rsRegColl: Reg path %s is in spec coll",
              dataObjInp.objPath);
            freeRodsObjStat (rodsObjStatOut);
            return (SYS_REG_OBJ_IN_SPEC_COLL);
	}
	freeRodsObjStat (rodsObjStatOut);
    }

    status = getAndConnRcatHost (rsComm, MASTER_RCAT, regCollInp->collName,
                                &rodsServerHost);
    if (status < 0) {
       return(status);
    }
    if (rodsServerHost->localFlag == LOCAL_HOST) {
#ifdef RODS_CAT
        status = _rsRegColl (rsComm, regCollInp);
#else
        status = SYS_NO_RCAT_SERVER_ERR;
#endif
    } else {
        status = rcRegColl (rodsServerHost->conn, regCollInp);
    }

    return (status);
}
Ejemplo n.º 3
0
int
rsDataObjCreate( rsComm_t *rsComm, dataObjInp_t *dataObjInp ) {
    int l1descInx;
    int status;
    rodsObjStat_t *rodsObjStatOut = NULL;
    int remoteFlag;
    rodsServerHost_t *rodsServerHost;
    specCollCache_t *specCollCache = NULL;
    char *lockType = NULL; // JMC - backport 4604
    int lockFd = -1; // JMC - backport 4604

    resolveLinkedPath( rsComm, dataObjInp->objPath, &specCollCache,
                       &dataObjInp->condInput );
    remoteFlag = getAndConnRemoteZone( rsComm, dataObjInp, &rodsServerHost,
                                       REMOTE_CREATE );
    if ( remoteFlag < 0 ) {
        return ( remoteFlag );
    }
    else if ( remoteFlag == REMOTE_HOST ) {
        openStat_t *openStat = NULL;
        addKeyVal( &dataObjInp->condInput, CROSS_ZONE_CREATE_KW, "" );
        status = rcDataObjCreateAndStat( rodsServerHost->conn, dataObjInp, &openStat );

        /* rm it to avoid confusion */
        rmKeyVal( &dataObjInp->condInput, CROSS_ZONE_CREATE_KW );
        if ( status < 0 ) {
            return status;
        }
        l1descInx = allocAndSetL1descForZoneOpr( status, dataObjInp, rodsServerHost, openStat );

        if ( openStat != NULL ) {
            free( openStat );
        }
        return ( l1descInx );
    }

    // =-=-=-=-=-=-=-
    // working on the "home zone", determine if we need to redirect to a different
    // server in this zone for this operation.  if there is a RESC_HIER_STR_KW then
    // we know that the redirection decision has already been made
    char* resc_hier = getValByKey( &dataObjInp->condInput, RESC_HIER_STR_KW );
    if ( NULL == resc_hier ) {
        std::string       hier;
        irods::error ret = irods::resolve_resource_hierarchy( irods::CREATE_OPERATION, rsComm,
                           dataObjInp, hier );
        if ( !ret.ok() ) {
            std::stringstream msg;
            msg << "failed in irods::resolve_resource_hierarchy for [";
            msg << dataObjInp->objPath << "]";
            irods::log( PASSMSG( msg.str(), ret ) );
            return ret.code();
        }

        // =-=-=-=-=-=-=-
        // we resolved the redirect and have a host, set the hier str for subsequent
        // api calls, etc.
        addKeyVal( &dataObjInp->condInput, RESC_HIER_STR_KW, hier.c_str() );

    } // if keyword

    // =-=-=-=-=-=-=-
    // JMC - backport 4604
    lockType = getValByKey( &dataObjInp->condInput, LOCK_TYPE_KW );
    if ( lockType != NULL ) {
        lockFd = rsDataObjLock( rsComm, dataObjInp );
        if ( lockFd >= 0 ) {
            /* rm it so it won't be done again causing deadlock */
            rmKeyVal( &dataObjInp->condInput, LOCK_TYPE_KW );
        }
        else {
            rodsLogError( LOG_ERROR, lockFd,
                          "rsDataObjCreate: rsDataObjLock error for %s. lockType = %s",
                          dataObjInp->objPath, lockType );
            return lockFd;
        }
    }

    // =-=-=-=-=-=-=-
    // Gets here means local zone operation stat dataObj
    addKeyVal( &dataObjInp->condInput, SEL_OBJ_TYPE_KW, "dataObj" );

    status = rsObjStat( rsComm, dataObjInp, &rodsObjStatOut );

    if ( rodsObjStatOut != NULL && rodsObjStatOut->objType == COLL_OBJ_T ) {
        if ( lockFd >= 0 ) {
            rsDataObjUnlock( rsComm, dataObjInp, lockFd );    // JMC - backport 4604
        }
        return ( USER_INPUT_PATH_ERR );
    }

    if ( rodsObjStatOut                      != NULL &&
            rodsObjStatOut->specColl            != NULL &&
            rodsObjStatOut->specColl->collClass == LINKED_COLL ) {
        /*  should not be here because if has been translated */
        if ( lockFd >= 0 ) {
            rsDataObjUnlock( rsComm, dataObjInp, lockFd ); // JMC - backport 4604
        }

        return SYS_COLL_LINK_PATH_ERR;
    }


    if ( rodsObjStatOut  == NULL                     ||
            ( rodsObjStatOut->objType  == UNKNOWN_OBJ_T &&
              rodsObjStatOut->specColl == NULL ) ) {
        /* does not exist. have to create one */
        /* use L1desc[l1descInx].replStatus & OPEN_EXISTING_COPY instead */
        /* newly created. take out FORCE_FLAG since it could be used by put */
        /* rmKeyVal (&dataObjInp->condInput, FORCE_FLAG_KW); */
        l1descInx = _rsDataObjCreate( rsComm, dataObjInp );

    }
    else if ( rodsObjStatOut->specColl != NULL &&
              rodsObjStatOut->objType == UNKNOWN_OBJ_T ) {

        /* newly created. take out FORCE_FLAG since it could be used by put */
        /* rmKeyVal (&dataObjInp->condInput, FORCE_FLAG_KW); */
        l1descInx = specCollSubCreate( rsComm, dataObjInp );
    }
    else {

        /* dataObj exist */
        if ( getValByKey( &dataObjInp->condInput, FORCE_FLAG_KW ) != NULL ) {
            dataObjInp->openFlags |= O_TRUNC | O_RDWR;

            // =-=-=-=-=-=-=-
            // re-determine the resource hierarchy since this is an open instead of a create
            std::string       hier;
            irods::error ret = irods::resolve_resource_hierarchy( irods::WRITE_OPERATION,
                               rsComm, dataObjInp, hier );
            if ( !ret.ok() ) {
                std::stringstream msg;
                msg << __FUNCTION__;
                msg << " :: failed in irods::resolve_resource_hierarchy for [";
                msg << dataObjInp->objPath << "]";
                irods::log( PASSMSG( msg.str(), ret ) );
                return ret.code();
            }

            // =-=-=-=-=-=-=-
            // we resolved the redirect and have a host, set the hier str for subsequent
            // api calls, etc.
            addKeyVal( &dataObjInp->condInput, RESC_HIER_STR_KW, hier.c_str() );
            std::string top_resc;
            irods::hierarchy_parser parser;
            parser.set_string( hier );
            parser.first_resc( top_resc );
            addKeyVal( &dataObjInp->condInput, DEST_RESC_NAME_KW, top_resc.c_str() );
            l1descInx = _rsDataObjOpen( rsComm, dataObjInp );

        }
        else {
            l1descInx = OVERWRITE_WITHOUT_FORCE_FLAG;
        }
    }

    if ( rodsObjStatOut != NULL ) {
        freeRodsObjStat( rodsObjStatOut );
    }

    // =-=-=-=-=-=-=-
    // JMC - backport 4604
    if ( lockFd >= 0 ) {
        if ( l1descInx >= 0 ) {
            L1desc[l1descInx].lockFd = lockFd;
        }
        else {
            rsDataObjUnlock( rsComm, dataObjInp, lockFd );
        }
    }

    // =-=-=-=-=-=-=-
    return ( l1descInx );
}
Ejemplo n.º 4
0
Archivo: xmlMS.c Proyecto: UPPMAX/irods
int 
msiLoadMetadataFromXml(msParam_t *targetObj, msParam_t *xmlObj, ruleExecInfo_t *rei) 
{
	/* for parsing msParams and to open iRODS objects */
	dataObjInp_t xmlDataObjInp, *myXmlDataObjInp;
	dataObjInp_t targetObjInp, *myTargetObjInp;
	int xmlObjID;

	/* for getting size of objects to read from */
	rodsObjStat_t *rodsObjStatOut = NULL;

	/* for reading from iRODS objects */
	openedDataObjInp_t openedDataObjInp;
	bytesBuf_t *xmlBuf;

	/* misc. to avoid repeating rei->rsComm */
	rsComm_t *rsComm;

	/* for xml parsing */
	xmlDocPtr doc;

	/* for XPath evaluation */
	xmlXPathContextPtr xpathCtx;
	xmlXPathObjectPtr xpathObj;
	xmlChar xpathExpr[] = "//AVU";
	xmlNodeSetPtr nodes;
	int avuNbr, i;
	
	/* for new AVU creation */
	modAVUMetadataInp_t modAVUMetadataInp;
	int max_attr_len = 2700;
	char attrStr[max_attr_len];



	/*********************************  USUAL INIT PROCEDURE **********************************/
	
	/* For testing mode when used with irule --test */
	RE_TEST_MACRO ("    Calling msiLoadMetadataFromXml")


	/* Sanity checks */
	if (rei == NULL || rei->rsComm == NULL)
	{
		rodsLog (LOG_ERROR, "msiLoadMetadataFromXml: input rei or rsComm is NULL.");
		return (SYS_INTERNAL_NULL_INPUT_ERR);
	}

	rsComm = rei->rsComm;


	
	/********************************** RETRIEVE INPUT PARAMS **************************************/

	/* Get path of target object */
	rei->status = parseMspForDataObjInp (targetObj, &targetObjInp, &myTargetObjInp, 0);
	if (rei->status < 0)
	{
		rodsLog (LOG_ERROR, "msiLoadMetadataFromXml: input targetObj error. status = %d", rei->status);
		return (rei->status);
	}


	/* Get path of XML document */
	rei->status = parseMspForDataObjInp (xmlObj, &xmlDataObjInp, &myXmlDataObjInp, 0);
	if (rei->status < 0)
	{
		rodsLog (LOG_ERROR, "msiLoadMetadataFromXml: input xmlObj error. status = %d", rei->status);
		return (rei->status);
	}



	/******************************** OPEN AND READ FROM XML OBJECT ********************************/

	/* Open XML file */
	if ((xmlObjID = rsDataObjOpen(rsComm, &xmlDataObjInp)) < 0) 
	{
		rodsLog (LOG_ERROR, "msiLoadMetadataFromXml: Cannot open XML data object. status = %d", xmlObjID);
		return (xmlObjID);
	}


	/* Get size of XML file */
	rei->status = rsObjStat (rsComm, &xmlDataObjInp, &rodsObjStatOut);
	if (rei->status < 0 || !rodsObjStatOut)
	{
		rodsLog (LOG_ERROR, "msiLoadMetadataFromXml: Cannot stat XML data object. status = %d", rei->status);
		return (rei->status);
	}


	/* xmlBuf init */
	/* memory for xmlBuf->buf is allocated in rsFileRead() */
	xmlBuf = (bytesBuf_t *) malloc (sizeof (bytesBuf_t));
	memset (xmlBuf, 0, sizeof (bytesBuf_t));


	/* Read XML file */
	memset (&openedDataObjInp, 0, sizeof (openedDataObjInp_t));
	openedDataObjInp.l1descInx = xmlObjID;
	openedDataObjInp.len = (int)rodsObjStatOut->objSize;

	rei->status = rsDataObjRead (rsComm, &openedDataObjInp, xmlBuf);
	
	/* Make sure that the result is null terminated */
	if (strlen((char*)xmlBuf->buf) > (size_t)openedDataObjInp.len)
	{
		((char*)xmlBuf->buf)[openedDataObjInp.len-1]='\0';
	}


	/* Close XML file */
	rei->status = rsDataObjClose (rsComm, &openedDataObjInp);

	/* cleanup */
	freeRodsObjStat (rodsObjStatOut);



	/******************************** PARSE XML DOCUMENT ********************************/

	xmlSubstituteEntitiesDefault(1);
	xmlLoadExtDtdDefaultValue = 1;


	/* Parse xmlBuf.buf into an xmlDocPtr */
	doc = xmlParseDoc((xmlChar*)xmlBuf->buf);


	/* Create xpath evaluation context */
	xpathCtx = xmlXPathNewContext(doc);
	if(xpathCtx == NULL) 
	{
		rodsLog (LOG_ERROR, "msiLoadMetadataFromXml: Unable to create new XPath context.");
		xmlFreeDoc(doc); 
		return(-1);
	}


	/* Evaluate xpath expression */
	xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx);
	if(xpathObj == NULL) 
	{
		rodsLog (LOG_ERROR, "msiLoadMetadataFromXml: Unable to evaluate XPath expression \"%s\".", xpathExpr);
		xmlXPathFreeContext(xpathCtx); 
		xmlFreeDoc(doc); 
		return(-1);
	}

	/* How many AVU nodes did we get? */
	if ((nodes = xpathObj->nodesetval) != NULL)
	{
		avuNbr = nodes->nodeNr;
	}
	else 
	{
		avuNbr = 0;
	}



	/******************************** CREATE AVU TRIPLETS ********************************/

	/* Add a new AVU for each node. It's ok to process the nodes in forward order since we're not modifying them */
	for(i = 0; i < avuNbr; i++) 
	{
		if (nodes->nodeTab[i])
		{
//			/* temporary: Add index number to avoid duplicating attribute names */
//			memset(attrStr, '\0', MAX_NAME_LEN);
//			snprintf(attrStr, MAX_NAME_LEN - 1, "%04d: %s", i+1, (char*)xmlNodeGetContent(getChildNodeByName(nodes->nodeTab[i], "Attribute")) );

			/* Truncate if needed. No prefix. */
			memset(attrStr, '\0', max_attr_len);
			snprintf(attrStr, max_attr_len - 1, "%s", (char*)xmlNodeGetContent(getChildNodeByName(nodes->nodeTab[i], "Attribute")) );

			/* init modAVU input */
			memset (&modAVUMetadataInp, 0, sizeof(modAVUMetadataInp_t));
			modAVUMetadataInp.arg0 = "add";
			modAVUMetadataInp.arg1 = "-d";

			/* Use target object if one was provided, otherwise look for it in the XML doc */
			if (myTargetObjInp->objPath != NULL && strlen(myTargetObjInp->objPath) > 0)
			{
				modAVUMetadataInp.arg2 = myTargetObjInp->objPath;
			}
			else
			{
				modAVUMetadataInp.arg2 = xmlURIUnescapeString((char*)xmlNodeGetContent(getChildNodeByName(nodes->nodeTab[i], "Target")),
						MAX_NAME_LEN, NULL);
			}

			modAVUMetadataInp.arg3 = attrStr;
			modAVUMetadataInp.arg4 = (char*)xmlNodeGetContent(getChildNodeByName(nodes->nodeTab[i], "Value"));
			modAVUMetadataInp.arg5 = (char*)xmlNodeGetContent(getChildNodeByName(nodes->nodeTab[i], "Unit"));
			
			/* invoke rsModAVUMetadata() */
			rei->status = rsModAVUMetadata (rsComm, &modAVUMetadataInp);
		}
	}



	/************************************** WE'RE DONE **************************************/

	/* cleanup of all xml parsing stuff */
	xmlFreeDoc(doc);
        xmlCleanupParser();

	return (rei->status);
}
Ejemplo n.º 5
0
Archivo: xmlMS.c Proyecto: UPPMAX/irods
/**
 * \fn msiXmlDocSchemaValidate(msParam_t *xmlObj, msParam_t *xsdObj, msParam_t *status, ruleExecInfo_t *rei)
 *
 * \brief  This microservice validates an XML file against an XSD schema, both iRODS objects.
 * 
 * \module xml
 * 
 * \since pre-2.1
 * 
 * \author  Antoine de Torcy
 * \date    2008/05/29
 * 
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[in] xmlObj - a msParam of type DataObjInp_MS_T or STR_MS_T which is irods path of the XML object.
 * \param[in] xsdObj - a msParam of type DataObjInp_MS_T or STR_MS_T which is irods path of the XSD object.
 * \param[out] status - a msParam of type INT_MS_T which is a validation result.
 * \param[in,out] rei - The RuleExecInfo structure that is automatically
 *    handled by the rule engine. The user does not include rei as a
 *    parameter in the rule invocation.
 *
 * \DolVarDependence None
 * \DolVarModified None
 * \iCatAttrDependence None
 * \iCatAttrModified None
 * \sideeffect None
 *
 * \return integer
 * \retval 0 on success
 * \pre None
 * \post None
 * \sa None
**/
int 
msiXmlDocSchemaValidate(msParam_t *xmlObj, msParam_t *xsdObj, msParam_t *status, ruleExecInfo_t *rei) 
{
	/* for parsing msParams and to open iRODS objects */
	dataObjInp_t xmlObjInp, *myXmlObjInp;
	dataObjInp_t xsdObjInp, *myXsdObjInp;
	int xmlObjID, xsdObjID;

	/* for getting size of objects to read from */
	rodsObjStat_t *rodsObjStatOut = NULL;

	/* for reading from iRODS objects */
	openedDataObjInp_t openedDataObjInp;
	bytesBuf_t *xmlBuf = NULL;
	char *tail;

	/* for xml parsing and validating */
	xmlDocPtr doc, xsd_doc;
	xmlSchemaParserCtxtPtr parser_ctxt;
	xmlSchemaPtr schema;
	xmlSchemaValidCtxtPtr valid_ctxt;
	bytesBuf_t *errBuf;

	/* misc. to avoid repeating rei->rsComm */
	rsComm_t *rsComm;



	/*************************************  USUAL INIT PROCEDURE **********************************/
	
	/* For testing mode when used with irule --test */
	RE_TEST_MACRO ("    Calling msiXmlDocSchemaValidate")


	/* Sanity checks */
	if (rei == NULL || rei->rsComm == NULL)
	{
		rodsLog (LOG_ERROR, "msiXmlDocSchemaValidate: input rei or rsComm is NULL.");
		return (SYS_INTERNAL_NULL_INPUT_ERR);
	}

	rsComm = rei->rsComm;



	/************************************ ADDITIONAL INIT SETTINGS *********************************/

	/* XML constants */
	xmlSubstituteEntitiesDefault(1);
	xmlLoadExtDtdDefaultValue = 1;


	/* allocate memory for output error buffer */
	errBuf = (bytesBuf_t *)malloc(sizeof(bytesBuf_t));
	errBuf->buf = strdup("");
	errBuf->len = strlen((char*)errBuf->buf);

	/* Default status is failure, overwrite if success */
	fillBufLenInMsParam (status, -1, NULL);

	
	/********************************** RETRIEVE INPUT PARAMS **************************************/

	/* Get path of XML document */
	rei->status = parseMspForDataObjInp (xmlObj, &xmlObjInp, &myXmlObjInp, 0);
	if (rei->status < 0)
	{
		rodsLog (LOG_ERROR, "msiXmlDocSchemaValidate: input xmlObj error. status = %d", rei->status);
		free(errBuf);
		return (rei->status);
	}


	/* Get path of schema */
	rei->status = parseMspForDataObjInp (xsdObj, &xsdObjInp, &myXsdObjInp, 0);
	if (rei->status < 0)
	{
		rodsLog (LOG_ERROR, "msiXmlDocSchemaValidate: input xsdObj error. status = %d", rei->status);
		free(errBuf);
		return (rei->status);
	}


	/******************************** OPEN AND READ FROM XML OBJECT ********************************/

	/* Open XML file */
	if ((xmlObjID = rsDataObjOpen(rsComm, &xmlObjInp)) < 0) 
	{
		rodsLog (LOG_ERROR, "msiXmlDocSchemaValidate: Cannot open XML data object. status = %d", xmlObjID);
		free(errBuf);
		return (xmlObjID);
	}


	/* Get size of XML file */
	rei->status = rsObjStat (rsComm, &xmlObjInp, &rodsObjStatOut);
	if (rei->status < 0 || !rodsObjStatOut)
	{
		rodsLog (LOG_ERROR, "msiXmlDocSchemaValidate: Cannot stat XML data object. status = %d", rei->status);
		free(errBuf);
		return (rei->status);
	}


	/* xmlBuf init */
	/* memory for xmlBuf->buf is allocated in rsFileRead() */
	xmlBuf = (bytesBuf_t *) malloc (sizeof (bytesBuf_t));
	memset (xmlBuf, 0, sizeof (bytesBuf_t));


	/* Read content of XML file */
	memset (&openedDataObjInp, 0, sizeof (openedDataObjInp_t));
	openedDataObjInp.l1descInx = xmlObjID;
	openedDataObjInp.len = (int)rodsObjStatOut->objSize + 1;	/* extra byte to add a null char */

	rei->status = rsDataObjRead (rsComm, &openedDataObjInp, xmlBuf);

	/* add terminating null character */
	tail = (char*)xmlBuf->buf;
	tail[openedDataObjInp.len - 1] = '\0';


	/* Close XML file */
	rei->status = rsDataObjClose (rsComm, &openedDataObjInp);

	/* cleanup */
	freeRodsObjStat (rodsObjStatOut);



	/*************************************** PARSE XML DOCUMENT **************************************/

	/* Parse xmlBuf.buf into an xmlDocPtr */
	doc = xmlParseDoc((xmlChar*)xmlBuf->buf);
	clearBBuf(xmlBuf);

	if (doc == NULL)
	{
		rodsLog (LOG_ERROR, "msiXmlDocSchemaValidate: XML document cannot be loaded or is not well-formed.");
		free(errBuf);
	    xmlCleanupParser();

	    return (USER_INPUT_FORMAT_ERR);
	}



	/******************************** OPEN AND READ FROM XSD OBJECT ********************************/

	/* Open schema file */
	if ((xsdObjID = rsDataObjOpen(rsComm, &xsdObjInp)) < 0) 
	{
		rodsLog (LOG_ERROR, "msiXmlDocSchemaValidate: Cannot open XSD data object. status = %d", xsdObjID);
		free(errBuf);
		xmlFreeDoc(doc);
	    xmlCleanupParser();

		return (xsdObjID);
	}


	/* Get size of schema file */
	rei->status = rsObjStat (rsComm, &xsdObjInp, &rodsObjStatOut);


	/* Read entire schema file */
	memset (&openedDataObjInp, 0, sizeof (openedDataObjInp_t));
	openedDataObjInp.l1descInx = xsdObjID;
	openedDataObjInp.len = (int)rodsObjStatOut->objSize + 1;	/* to add null char */

	rei->status = rsDataObjRead (rsComm, &openedDataObjInp, xmlBuf);

	/* add terminating null character */
	tail = (char*)xmlBuf->buf;
	tail[openedDataObjInp.len - 1] = '\0';


	/* Close schema file */
	rei->status = rsDataObjClose (rsComm, &openedDataObjInp);

	/* cleanup */
	freeRodsObjStat (rodsObjStatOut);



	/*************************************** PARSE XSD DOCUMENT **************************************/

	/* Parse xmlBuf.buf into an xmlDocPtr */
	xsd_doc = xmlParseDoc((xmlChar*)xmlBuf->buf);
	clearBBuf(xmlBuf);

	if (xsd_doc == NULL)
	{
		rodsLog (LOG_ERROR, "msiXmlDocSchemaValidate: XML Schema cannot be loaded or is not well-formed.");
		free(errBuf);
		xmlFreeDoc(doc);
		xmlCleanupParser();

	    return (USER_INPUT_FORMAT_ERR);
	}



	/**************************************** VALIDATE DOCUMENT **************************************/

	/* Create a parser context */
	parser_ctxt = xmlSchemaNewDocParserCtxt(xsd_doc);
	if (parser_ctxt == NULL)
	{
		rodsLog (LOG_ERROR, "msiXmlDocSchemaValidate: Unable to create a parser context for the schema.");
		free(errBuf);
		xmlFreeDoc(xsd_doc);
		xmlFreeDoc(doc);
	    xmlCleanupParser();

	    return (USER_INPUT_FORMAT_ERR);
	}


	/* Parse the XML schema */
	schema = xmlSchemaParse(parser_ctxt);
	if (schema == NULL) 
	{
		rodsLog (LOG_ERROR, "msiXmlDocSchemaValidate: Invalid schema.");
		free(errBuf);
		xmlSchemaFreeParserCtxt(parser_ctxt);
		xmlFreeDoc(doc);
		xmlFreeDoc(xsd_doc);
        xmlCleanupParser();

	    return (USER_INPUT_FORMAT_ERR);
	}


	/* Create a validation context */
	valid_ctxt = xmlSchemaNewValidCtxt(schema);
	if (valid_ctxt == NULL) 
	{
		rodsLog (LOG_ERROR, "msiXmlDocSchemaValidate: Unable to create a validation context for the schema.");
		free(errBuf);
		xmlSchemaFree(schema);
		xmlSchemaFreeParserCtxt(parser_ctxt);
		xmlFreeDoc(xsd_doc);
		xmlFreeDoc(doc);
	    xmlCleanupParser();

	    return (USER_INPUT_FORMAT_ERR);
	}


	/* Set myErrorCallback() as the default handler for error messages and warnings */
	xmlSchemaSetValidErrors(valid_ctxt, (xmlSchemaValidityErrorFunc)myErrorCallback, (xmlSchemaValidityWarningFunc)myErrorCallback, errBuf);


	/* Validate XML doc */
	rei->status = xmlSchemaValidateDoc(valid_ctxt, doc);



	/******************************************* WE'RE DONE ******************************************/

	/* return both error code and messages through status */
	resetMsParam (status);
	fillBufLenInMsParam (status, rei->status, errBuf);


	/* cleanup of all xml parsing stuff */
	xmlSchemaFreeValidCtxt(valid_ctxt);
	xmlSchemaFree(schema);
	xmlSchemaFreeParserCtxt(parser_ctxt);
	xmlFreeDoc(doc);
	xmlFreeDoc(xsd_doc);
	xmlCleanupParser();

	return (rei->status);
}