Exemple #1
0
int
rsMkCollR( rsComm_t *rsComm, const char *startColl, const char *destColl ) {
    int status;
    int startLen;
    int pathLen, tmpLen;
    char tmpPath[MAX_NAME_LEN];

    startLen = strlen( startColl );
    pathLen = strlen( destColl );

    rstrcpy( tmpPath, destColl, MAX_NAME_LEN );

    tmpLen = pathLen;

    while ( tmpLen > startLen ) {
        if ( isCollAllKinds( rsComm, tmpPath, NULL ) >= 0 ) {
            break;
        }

        /* Go backward */

        while ( tmpLen && tmpPath[tmpLen] != '/' ) {
            tmpLen --;
        }
        tmpPath[tmpLen] = '\0';
    }

    /* Now we go forward and make the required coll */
    while ( tmpLen < pathLen ) {
        collInp_t collCreateInp;

        /* Put back the '/' */
        tmpPath[tmpLen] = '/';
        memset( &collCreateInp, 0, sizeof( collCreateInp ) );
        rstrcpy( collCreateInp.collName, tmpPath, MAX_NAME_LEN );
        status = rsCollCreate( rsComm, &collCreateInp );

        if ( status == CAT_NAME_EXISTS_AS_DATAOBJ && isTrashPath( tmpPath ) ) {
            /* name conflict with a data object in the trash collection */
            dataObjCopyInp_t dataObjRenameInp;
            memset( &dataObjRenameInp, 0, sizeof( dataObjRenameInp ) );

            dataObjRenameInp.srcDataObjInp.oprType =
                dataObjRenameInp.destDataObjInp.oprType = RENAME_DATA_OBJ;
            rstrcpy( dataObjRenameInp.srcDataObjInp.objPath, tmpPath,
                     MAX_NAME_LEN );
            rstrcpy( dataObjRenameInp.destDataObjInp.objPath, tmpPath,
                     MAX_NAME_LEN );
            appendRandomToPath( dataObjRenameInp.destDataObjInp.objPath );

            status = rsDataObjRename( rsComm, &dataObjRenameInp );
            if ( status >= 0 ) {
                status = rsCollCreate( rsComm, &collCreateInp );
            }
        }
        /* something may be added by rsCollCreate */
        clearKeyVal( &collCreateInp.condInput );
        if ( status < 0 ) {
            // =-=-=-=-=-=-=-
            // JMC - backport 4819
            if ( status == CATALOG_ALREADY_HAS_ITEM_BY_THAT_NAME ) {
                rodsLog( LOG_DEBUG,
                         "rsMkCollR: rsCollCreate - coll %s already exist.stat = %d",
                         tmpPath, status );
                status = 0;
            }
            else {
                rodsLog( LOG_ERROR,
                         "rsMkCollR: rsCollCreate failed for %s, status =%d",
                         tmpPath, status );
            }
            // =-=-=-=-=-=-=-
            return status;
        }
        while ( tmpLen && tmpPath[tmpLen] != '\0' ) {
            tmpLen ++;
        }
    }
    return 0;
}
/**
 * \fn msiServerBackup(msParam_t *options, msParam_t *keyValOut, ruleExecInfo_t *rei)
 *
 * \brief Copies iRODS server files to the local resource
 *
 * \module core
 *
 * \since 3.0.x
 *
 * \author  Antoine de Torcy
 * \date    2011-05-25
 *
 * \note  Copies server files to the local vault and registers them.
 *    Object (.o) files and binaries are not included.
 *
 * \note Files are stored in the Vault under a directory of the format: hostname_timestamp
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[in] options - Optional - a STR_MS_T that contains one of more options in
 *      the format keyWd1=value1++++keyWd2=value2++++keyWd3=value3...
 *      A placeholder for now.
 * \param[out] keyValOut - a KeyValPair_MS_T with the number of files and bytes written.
 * \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 Some
 * \sideeffect None
 *
 * \return integer
 * \retval 0 on success
 * \pre None
 * \post None
 * \sa None
**/
int
msiServerBackup(msParam_t *options, msParam_t *keyValOut, ruleExecInfo_t *rei)
{
	keyValPair_t *myKeyVal;						/* for storing results */
	collInp_t collInp;							/* for creating and opening collections */

	dataObjInp_t dataObjInp;					/* for collection registration */

	char tStr0[TIME_LEN], tStr[TIME_LEN];		/* for timestamp */

	char newDirPath[MAX_NAME_LEN];				/* physical path of new directory on resource */

	rescInfo_t *rescInfo;						/* for local resource info */
	char *dbPath;								/* local iCAT home dir */

	char *rodsDirPath, *subPath;
	size_t offset;

	int fileCount, status;						/* counters, status, etc... */
	char fileCountStr[21];



	/* For testing mode when used with irule --test */
	RE_TEST_MACRO ("    Calling msiServerBackup")

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


	/* Must be called from an admin account */
	if (rei->uoic->authInfo.authFlag < LOCAL_PRIV_USER_AUTH)
	{
		status = CAT_INSUFFICIENT_PRIVILEGE_LEVEL;
		rodsLog (LOG_ERROR, "msiServerBackup: User %s is not local admin. Status = %d",
				rei->uoic->userName, status);
		return(status);
	}


	/* Get icat home dir, if applicable */
	dbPath = getDBHomeDir();

	/* Get local resource info */
	status = getDefaultLocalRescInfo(&rescInfo);
	if (status < 0)
	{
		rodsLog (LOG_ERROR, "msiServerBackup: Could not resolve local resource, status = %d",
				status);
		if (dbPath) {
			free(dbPath);
		}
        return (status);
	}


	/* Get path of iRODS home directory */
	if  ((rodsDirPath = getenv("irodsHomeDir")) == NULL)
	{
		rodsLog (LOG_ERROR, "msiServerBackup: Cannot find directory to back up.");
		if (dbPath) {
			free(dbPath);
		}
        return (USER_INPUT_PATH_ERR);
	}


	/***** Create target directory for copy, whose name is made
	 ****** of the hostname and timestamp ********************/

    /* get timestamp */
	getNowStr (tStr0);
	getLocalTimeFromRodsTime (tStr0,tStr);

	/**********************************/


	/* Prepare myKeyVal so that we can dump
	 * data in it throughout the microservice */
	myKeyVal = (keyValPair_t*) malloc (sizeof(keyValPair_t));
	memset (myKeyVal, 0, sizeof(keyValPair_t));
	keyValOut->type = strdup(KeyValPair_MS_T);



	/* Store local and target directories in myKeyVal, along with other useful stuff */

	/* Calculate offset */
	offset = strrchr(rodsDirPath,'/') - rodsDirPath + 1;


	/*******************************************/


	/************ invoke loadDirToLocalResc ***************************/

	fileCount = loadDirToLocalResc(rei, rodsDirPath, offset, rescInfo->rescVaultPath, tStr, dbPath);

	/* get some cleanup out of the way */
	if (dbPath) {
		free(dbPath);
	}

	if (rei->status < 0)
	{
		rodsLog (LOG_ERROR, "msiServerBackup: loadDirToLocalResc() error, status = %d",
				rei->status);
		free(myKeyVal);
		return rei->status;
	}

	/******************************************************/


	/* We need to create a parent collection prior to registering our directory */
	/* set up collection creation input */
	memset (&collInp, 0, sizeof(collInp_t));
	addKeyVal (&collInp.condInput, RECURSIVE_OPR__KW, "");

	/* build path of target collection */
	snprintf(collInp.collName, MAX_NAME_LEN, "%s/%s/%s_%s", rei->rsComm->myEnv.rodsHome,
			BCKP_COLL_NAME, rei->rsComm->myEnv.rodsHost, tStr);

	/* make target collection */
	rei->status = rsCollCreate (rei->rsComm, &collInp);
	if (rei->status < 0)
	{
		rodsLog (LOG_ERROR, "msiServerBackup: rsCollCreate failed for %s, status = %d",
				collInp.collName, rei->status);
		free(myKeyVal);
		return (rei->status);
	}


	/* Register our new directory in the vault */

	/* Input setup */
	memset(&dataObjInp, 0, sizeof(dataObjInp_t));
	addKeyVal (&dataObjInp.condInput, COLLECTION_KW, "");
	addKeyVal (&dataObjInp.condInput, DEST_RESC_NAME_KW, rescInfo->rescName);

	/* Separated for clarity. Typically this chunk is 'home/$username' */
	subPath = rei->rsComm->myEnv.rodsHome + strlen(rei->rsComm->myEnv.rodsZone) + 2;

	/* Reconstruct path of new dir on resource */
	snprintf(newDirPath, MAX_NAME_LEN, "%s/%s/%s/%s_%s/%s", rescInfo->rescVaultPath,
			subPath, BCKP_COLL_NAME, rei->rsComm->myEnv.rodsHost, tStr, rodsDirPath + offset);

	addKeyVal (&dataObjInp.condInput, FILE_PATH_KW, newDirPath);

	/* Similarly, reconstruct iRODS path of (target) new collection */
	snprintf(dataObjInp.objPath, MAX_NAME_LEN, "%s/%s/%s_%s/%s", rei->rsComm->myEnv.rodsHome,
			BCKP_COLL_NAME, rei->rsComm->myEnv.rodsHost, tStr, rodsDirPath + offset);


	/* Registration happens here */
	rei->status = rsPhyPathReg (rei->rsComm, &dataObjInp);
	if (rei->status < 0)
	{
		rodsLog (LOG_ERROR, "msiServerBackup: rsPhyPathReg() failed with status %d", rei->status);
		free(myKeyVal);
		return rei->status;
	}


	/* Add file count to myKeyVal */
	snprintf(fileCountStr, 21, "%d", fileCount);
	addKeyVal(myKeyVal, "object_count", fileCountStr);  // stub

	/* Return myKeyVal through keyValOut */
	keyValOut->inOutStruct = (void*) myKeyVal;


	/* Done! */
	return 0;
}
Exemple #3
0
int
dirPathReg (rsComm_t *rsComm, dataObjInp_t *phyPathRegInp, char *filePath,
rescInfo_t *rescInfo)
{
    collInp_t collCreateInp;
    fileOpendirInp_t fileOpendirInp;
    fileClosedirInp_t fileClosedirInp;
    int rescTypeInx;
    int status;
    int dirFd;
    dataObjInp_t subPhyPathRegInp;
    fileReaddirInp_t fileReaddirInp;
    rodsDirent_t *rodsDirent = NULL;
    rodsObjStat_t *rodsObjStatOut = NULL;
    int forceFlag;
    fileStatInp_t fileStatInp;
    rodsStat_t *myStat = NULL;

    rescTypeInx = rescInfo->rescTypeInx;

    status = collStat (rsComm, phyPathRegInp, &rodsObjStatOut);
    if (status < 0) {
        memset (&collCreateInp, 0, sizeof (collCreateInp));
        rstrcpy (collCreateInp.collName, phyPathRegInp->objPath, 
	  MAX_NAME_LEN);
	/* no need to resolve sym link */
	addKeyVal (&collCreateInp.condInput, TRANSLATED_PATH_KW, "");
#ifdef FILESYSTEM_META
        /* stat the source directory to track the         */
        /* original directory meta-data                   */
        memset (&fileStatInp, 0, sizeof (fileStatInp));
        rstrcpy (fileStatInp.fileName, filePath, MAX_NAME_LEN);
        fileStatInp.fileType = (fileDriverType_t)RescTypeDef[rescTypeInx].driverType;
        rstrcpy (fileStatInp.addr.hostAddr, rescInfo->rescLoc, NAME_LEN);

        status = rsFileStat (rsComm, &fileStatInp, &myStat);
        if (status != 0) {
            rodsLog (LOG_ERROR,
	      "dirPathReg: rsFileStat failed for %s, status = %d",
	      filePath, status);
	    return (status);
        }
        getFileMetaFromStat (myStat, &collCreateInp.condInput);
        addKeyVal(&collCreateInp.condInput, FILE_SOURCE_PATH_KW, filePath);
        free (myStat);
#endif /* FILESYSTEM_META */
        /* create the coll just in case it does not exist */
        status = rsCollCreate (rsComm, &collCreateInp);
	clearKeyVal (&collCreateInp.condInput);
	if (status < 0) return status;
    } else if (rodsObjStatOut->specColl != NULL) {
        freeRodsObjStat (rodsObjStatOut);
        rodsLog (LOG_ERROR,
          "mountFileDir: %s already mounted", phyPathRegInp->objPath);
        return (SYS_MOUNT_MOUNTED_COLL_ERR);
    }
    freeRodsObjStat (rodsObjStatOut);

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

    rstrcpy (fileOpendirInp.dirName, filePath, MAX_NAME_LEN);
    fileOpendirInp.fileType = (fileDriverType_t)RescTypeDef[rescTypeInx].driverType;
    rstrcpy (fileOpendirInp.addr.hostAddr,  rescInfo->rescLoc, NAME_LEN);

    dirFd = rsFileOpendir (rsComm, &fileOpendirInp);
    if (dirFd < 0) {
       rodsLog (LOG_ERROR,
          "dirPathReg: rsFileOpendir for %s error, status = %d",
          filePath, dirFd);
        return (dirFd);
    }

    fileReaddirInp.fileInx = dirFd;

    if (getValByKey (&phyPathRegInp->condInput, FORCE_FLAG_KW) != NULL) {
	forceFlag = 1;
    } else {
	forceFlag = 0;
    }

    while ((status = rsFileReaddir (rsComm, &fileReaddirInp, &rodsDirent))
      >= 0) {

        if (strcmp (rodsDirent->d_name, ".") == 0 ||
          strcmp (rodsDirent->d_name, "..") == 0) {
	    free (rodsDirent);
            continue;
        }

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

        snprintf (fileStatInp.fileName, MAX_NAME_LEN, "%s/%s",
          filePath, rodsDirent->d_name);

        fileStatInp.fileType = fileOpendirInp.fileType; 
	fileStatInp.addr = fileOpendirInp.addr;
        myStat = NULL;
        status = rsFileStat (rsComm, &fileStatInp, &myStat);

	if (status != 0) {
            rodsLog (LOG_ERROR,
	      "dirPathReg: rsFileStat failed for %s, status = %d",
	      fileStatInp.fileName, status);
	    free (rodsDirent);
	    return (status);
	}

	subPhyPathRegInp = *phyPathRegInp;
	snprintf (subPhyPathRegInp.objPath, MAX_NAME_LEN, "%s/%s",
	  phyPathRegInp->objPath, rodsDirent->d_name);

	if ((myStat->st_mode & S_IFREG) != 0) {     /* a file */
	    if (forceFlag > 0) {
		/* check if it already exists */
	        if (isData (rsComm, subPhyPathRegInp.objPath, NULL) >= 0) {
		    free (myStat);
	            free (rodsDirent);
		    continue;
		}
	    }
	    subPhyPathRegInp.dataSize = myStat->st_size;
	    if (getValByKey (&phyPathRegInp->condInput, REG_REPL_KW) != NULL) {
                status = filePathRegRepl (rsComm, &subPhyPathRegInp,
                  fileStatInp.fileName, rescInfo);
	    } else {
                addKeyVal (&subPhyPathRegInp.condInput, FILE_PATH_KW, 
	          fileStatInp.fileName);
	        status = filePathReg (rsComm, &subPhyPathRegInp, 
	          fileStatInp.fileName, rescInfo);
	    }
        } else if ((myStat->st_mode & S_IFDIR) != 0) {      /* a directory */
            status = dirPathReg (rsComm, &subPhyPathRegInp,
              fileStatInp.fileName, rescInfo);
	}
	free (myStat);
	free (rodsDirent);
    }
    if (status == -1) {         /* just EOF */
        status = 0;
    }

    fileClosedirInp.fileInx = dirFd;
    rsFileClosedir (rsComm, &fileClosedirInp);

    return (status);
}
Exemple #4
0
int
dirPathReg (rsComm_t *rsComm, dataObjInp_t *phyPathRegInp, char *filePath,
rescInfo_t *rescInfo)
{
    collInp_t collCreateInp;
    fileOpendirInp_t fileOpendirInp;
    fileClosedirInp_t fileClosedirInp;
    int rescTypeInx;
    int status;
    int dirFd;
    dataObjInp_t subPhyPathRegInp;
    fileReaddirInp_t fileReaddirInp;
    rodsDirent_t *rodsDirent = NULL;
    rodsObjStat_t *rodsObjStatOut = NULL;

    status = collStat (rsComm, phyPathRegInp, &rodsObjStatOut);
    if (status < 0) {
        memset (&collCreateInp, 0, sizeof (collCreateInp));
        rstrcpy (collCreateInp.collName, phyPathRegInp->objPath, 
	  MAX_NAME_LEN);
        /* create the coll just in case it does not exist */
        status = rsCollCreate (rsComm, &collCreateInp);
	if (status < 0) return status;
    } else if (rodsObjStatOut->specColl != NULL) {
        free (rodsObjStatOut);
        rodsLog (LOG_ERROR,
          "mountFileDir: %s already mounted", phyPathRegInp->objPath);
        return (SYS_MOUNT_MOUNTED_COLL_ERR);
    }
    free (rodsObjStatOut);

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

    rescTypeInx = rescInfo->rescTypeInx;
    rstrcpy (fileOpendirInp.dirName, filePath, MAX_NAME_LEN);
    fileOpendirInp.fileType = RescTypeDef[rescTypeInx].driverType;
    rstrcpy (fileOpendirInp.addr.hostAddr,  rescInfo->rescLoc, NAME_LEN);

    dirFd = rsFileOpendir (rsComm, &fileOpendirInp);
    if (dirFd < 0) {
       rodsLog (LOG_ERROR,
          "dirPathReg: rsFileOpendir for %s error, status = %d",
          filePath, dirFd);
        return (dirFd);
    }

    fileReaddirInp.fileInx = dirFd;

    while ((status = rsFileReaddir (rsComm, &fileReaddirInp, &rodsDirent))
      >= 0) {
        fileStatInp_t fileStatInp;
	rodsStat_t *myStat = NULL;

        if (strcmp (rodsDirent->d_name, ".") == 0 ||
          strcmp (rodsDirent->d_name, "..") == 0) {
            continue;
        }

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

        snprintf (fileStatInp.fileName, MAX_NAME_LEN, "%s/%s",
          filePath, rodsDirent->d_name);

        fileStatInp.fileType = fileOpendirInp.fileType; 
	fileStatInp.addr = fileOpendirInp.addr;
        status = rsFileStat (rsComm, &fileStatInp, &myStat);

	if (status != 0) {
            rodsLog (LOG_ERROR,
	      "dirPathReg: rsFileStat failed for %s, status = %d",
	      fileStatInp.fileName, status);
	    return (status);
	}

	subPhyPathRegInp = *phyPathRegInp;
	snprintf (subPhyPathRegInp.objPath, MAX_NAME_LEN, "%s/%s",
	  phyPathRegInp->objPath, rodsDirent->d_name);

	if ((myStat->st_mode & S_IFREG) != 0) {     /* a file */
            addKeyVal (&subPhyPathRegInp.condInput, FILE_PATH_KW, 
	      fileStatInp.fileName);
	    subPhyPathRegInp.dataSize = myStat->st_size;
	    status = filePathReg (rsComm, &subPhyPathRegInp, 
	      fileStatInp.fileName, rescInfo);
        } else if ((myStat->st_mode & S_IFDIR) != 0) {      /* a directory */
            status = dirPathReg (rsComm, &subPhyPathRegInp,
              fileStatInp.fileName, rescInfo);
	}
	free (myStat);
    }
    if (status == -1) {         /* just EOF */
        status = 0;
    }

    fileClosedirInp.fileInx = dirFd;
    rsFileClosedir (rsComm, &fileClosedirInp);

    return (status);
}
Exemple #5
0
int
dirPathReg (rsComm_t *rsComm, dataObjInp_t *phyPathRegInp, char *filePath,
rescInfo_t *rescInfo)
{
    collInp_t collCreateInp;
    fileOpendirInp_t fileOpendirInp;
    fileClosedirInp_t fileClosedirInp;
    int rescTypeInx;
    int status;
    int dirFd;
    dataObjInp_t subPhyPathRegInp;
    fileReaddirInp_t fileReaddirInp;
    rodsDirent_t *rodsDirent = NULL;
    rodsObjStat_t *rodsObjStatOut = NULL;
    int forceFlag;
    fileStatInp_t fileStatInp;
    rodsStat_t *myStat = NULL;
    char curcoll[MAX_NAME_LEN];

    *curcoll = '\0';
    rescTypeInx = rescInfo->rescTypeInx;

    status = collStat (rsComm, phyPathRegInp, &rodsObjStatOut);
    if (status < 0) {
        memset (&collCreateInp, 0, sizeof (collCreateInp));
        rstrcpy (collCreateInp.collName, phyPathRegInp->objPath, 
	  MAX_NAME_LEN);
	/* no need to resolve sym link */
	addKeyVal (&collCreateInp.condInput, TRANSLATED_PATH_KW, "");
#ifdef FILESYSTEM_META
        /* stat the source directory to track the         */
        /* original directory meta-data                   */
        memset (&fileStatInp, 0, sizeof (fileStatInp));
        rstrcpy (fileStatInp.fileName, filePath, MAX_NAME_LEN);
        fileStatInp.fileType = (fileDriverType_t)RescTypeDef[rescTypeInx].driverType;
        rstrcpy (fileStatInp.addr.hostAddr, rescInfo->rescLoc, NAME_LEN);

        status = rsFileStat (rsComm, &fileStatInp, &myStat);
        if (status != 0) {
            rodsLog (LOG_ERROR,
	      "dirPathReg: rsFileStat failed for %s, status = %d",
	      filePath, status);
	    return (status);
        }
        getFileMetaFromStat (myStat, &collCreateInp.condInput);
        addKeyVal(&collCreateInp.condInput, FILE_SOURCE_PATH_KW, filePath);
        free (myStat);
#endif /* FILESYSTEM_META */
        /* create the coll just in case it does not exist */
        status = rsCollCreate (rsComm, &collCreateInp);
	clearKeyVal (&collCreateInp.condInput);
	if (status < 0) {
            rodsLog (LOG_ERROR,
              "dirPathReg: rsCollCreate %s error. status = %d", 
              phyPathRegInp->objPath, status);
            return status;
        }
    } else if (rodsObjStatOut->specColl != NULL) {
        freeRodsObjStat (rodsObjStatOut);
        rodsLog (LOG_ERROR,
          "dirPathReg: %s already mounted", phyPathRegInp->objPath);
        return (SYS_MOUNT_MOUNTED_COLL_ERR);
    }
    freeRodsObjStat (rodsObjStatOut);

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

    rstrcpy (fileOpendirInp.dirName, filePath, MAX_NAME_LEN);
    fileOpendirInp.fileType = (fileDriverType_t)RescTypeDef[rescTypeInx].driverType;
    rstrcpy (fileOpendirInp.addr.hostAddr,  rescInfo->rescLoc, NAME_LEN);

    dirFd = rsFileOpendir (rsComm, &fileOpendirInp);
    if (dirFd < 0) {
       rodsLog (LOG_ERROR,
          "dirPathReg: rsFileOpendir for %s error, status = %d",
          filePath, dirFd);
        return (dirFd);
    }

    fileReaddirInp.fileInx = dirFd;

    if (getValByKey (&phyPathRegInp->condInput, FORCE_FLAG_KW) != NULL) {
	forceFlag = 1;
    } else {
	forceFlag = 0;
    }

    while ((status = rsFileReaddir (rsComm, &fileReaddirInp, &rodsDirent))
      >= 0) {
	int len;

        if (strlen (rodsDirent->d_name) == 0) break;

        if (strcmp (rodsDirent->d_name, ".") == 0 ||
          strcmp (rodsDirent->d_name, "..") == 0) {
	    free (rodsDirent);
            continue;
        }

        if (matchPathname(ExcludePatterns, rodsDirent->d_name, filePath)) {
            continue;
        }

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

        if (RescTypeDef[rescTypeInx].incParentDir == NO_INC_PARENT_DIR) {
	    /* don't include parent path */
            snprintf (fileStatInp.fileName, MAX_NAME_LEN, "%s",
             rodsDirent->d_name);
        } else if (RescTypeDef[rescTypeInx].incParentDir == 
          PHYPATH_IN_DIR_PTR) {
            /* we can do this locally because this API is executed at the
             * resource server */
            getPhyPathInOpenedDir (dirFd, rodsDirent->d_ino, 
              fileStatInp.fileName);
        } else {
	    len = strlen (filePath);
	    if (filePath[len - 1] == '/') {
                /* already has a '/' */
                snprintf (fileStatInp.fileName, MAX_NAME_LEN, "%s%s",
                 filePath, rodsDirent->d_name);
            } else {
                snprintf (fileStatInp.fileName, MAX_NAME_LEN, "%s/%s",
                  filePath, rodsDirent->d_name);
            }
        }
        fileStatInp.fileType = fileOpendirInp.fileType; 
	fileStatInp.addr = fileOpendirInp.addr;
        myStat = NULL;
        status = rsFileStat (rsComm, &fileStatInp, &myStat);

	if (status != 0) {
            rodsLog (LOG_ERROR,
	      "dirPathReg: rsFileStat failed for %s, status = %d",
	      fileStatInp.fileName, status);
	    free (rodsDirent);
	    return (status);
	}

        if (RescTypeDef[rescTypeInx].driverType == TDS_FILE_TYPE &&
          strchr (rodsDirent->d_name, '/') != NULL) {
            /* TDS may contain '/' in the file path */
            char *tmpPtr = rodsDirent->d_name;
            /* replace '/' with '.' */
            while (*tmpPtr != '\0') {
               if (*tmpPtr == '/') *tmpPtr = '.';
               tmpPtr ++;
            }
        }
        if (RescTypeDef[rescTypeInx].incParentDir == PHYPATH_IN_DIR_PTR) {
            /* the st_mode is stored in the opened dir */
            myStat->st_mode = getStModeInOpenedDir (dirFd, rodsDirent->d_ino);
            freePhyPathInOpenedDir (dirFd, rodsDirent->d_ino);
        }
	subPhyPathRegInp = *phyPathRegInp;
        if (RescTypeDef[rescTypeInx].incParentDir == NO_INC_PARENT_DIR) {
	    char myDir[MAX_NAME_LEN], myFile[MAX_NAME_LEN];
	    /* d_name is a full path, need to split it */
            if ((status = splitPathByKey (rodsDirent->d_name, myDir, myFile, 
              '/')) < 0) {
                rodsLog (LOG_ERROR,
                  "dirPathReg: splitPathByKey error for %s ", 
                  rodsDirent->d_name);
                continue;
            }
	    snprintf (subPhyPathRegInp.objPath, MAX_NAME_LEN, "%s/%s",
	      phyPathRegInp->objPath, myFile);
        } else if (RescTypeDef[rescTypeInx].incParentDir == 
            PHYPATH_IN_DIR_PTR) {
            char curdir[MAX_NAME_LEN];
            *curdir = '\0';
            getCurDirInOpenedDir (dirFd, curdir);
            if (strlen (curdir) > 0) {
                /* see if we have done it already */
                int len = strlen (subPhyPathRegInp.objPath);
                if (*curcoll == '\0'  || 
                  strcmp (&curcoll[len + 1], curdir) != 0) {
                    snprintf (curcoll, MAX_NAME_LEN, "%s/%s",
                      phyPathRegInp->objPath, curdir);
                    rsMkCollR (rsComm, phyPathRegInp->objPath, curcoll);
                }
	        snprintf (subPhyPathRegInp.objPath, MAX_NAME_LEN, "%s/%s",
	          curcoll, rodsDirent->d_name);
            } else {
                snprintf (subPhyPathRegInp.objPath, MAX_NAME_LEN, "%s/%s",
                  phyPathRegInp->objPath, rodsDirent->d_name);
            }
        } else {
	    snprintf (subPhyPathRegInp.objPath, MAX_NAME_LEN, "%s/%s",
	      phyPathRegInp->objPath, rodsDirent->d_name);
        }
	if ((myStat->st_mode & S_IFREG) != 0) {     /* a file */
	    if (forceFlag > 0) {
		/* check if it already exists */
	        if (isData (rsComm, subPhyPathRegInp.objPath, NULL) >= 0) {
		    free (myStat);
	            free (rodsDirent);
		    continue;
		}
	    }
	    subPhyPathRegInp.dataSize = myStat->st_size;
	    if (getValByKey (&phyPathRegInp->condInput, REG_REPL_KW) != NULL) {
                status = filePathRegRepl (rsComm, &subPhyPathRegInp,
                  fileStatInp.fileName, rescInfo);
	    } else {
                addKeyVal (&subPhyPathRegInp.condInput, FILE_PATH_KW, 
	          fileStatInp.fileName);
	        status = filePathReg (rsComm, &subPhyPathRegInp, 
	          fileStatInp.fileName, rescInfo);
	    }
        } else if ((myStat->st_mode & S_IFDIR) != 0) {      /* a directory */
            len = strlen (subPhyPathRegInp.objPath);
            if (subPhyPathRegInp.objPath[len - 1] == '/') {
                /* take out the end '/' for objPath */
                subPhyPathRegInp.objPath[len - 1] = '\0';
            }
            status = dirPathReg (rsComm, &subPhyPathRegInp,
              fileStatInp.fileName, rescInfo);
	}
        if (status < 0) return status;
	free (myStat);
	free (rodsDirent);
    }
    if (status == -1) {         /* just EOF */
        status = 0;
    }

    fileClosedirInp.fileInx = dirFd;
    rsFileClosedir (rsComm, &fileClosedirInp);

    return (status);
}
/**
 * \fn msiDataObjAutoMove(msParam_t *inpParam1, msParam_t *inpParam2, msParam_t *inpParam3,
 *                      msParam_t *inpParam4, msParam_t *inpParam5, ruleExecInfo_t *rei)
 *
 * \brief This microservice is used to automatically move the newly created file into a destination collection.
 *
 * \module core
 *
 * \since 2.2
 *
 * \author  Bing Zhu
 * \date    2009-07
 *
 * \note This microservice changes the ownership for the dataset(s) being moved.
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[in] inpParam1 - a STR_MS_T containing the object name with path. It usually comes from query as "$objPat
 *                          like /zone/../%" in the deployed microservice
 * \param[in] inpParam2 - a STR_MS_T containing the leading collection name to be truncated
 * \param[in] inpParam3 - a STR_MS_T containing the destination collection
 * \param[in] inpParam4 - a STR_MS_T containing the new owner
 * \param[in] inpParam5 - a STR_MS_T containing a flag for whether the checksum should be computed
                        \li true - default - will compute the checksum
                        \li false - will not compute the checksum
 * \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 upon success
 * \pre none
 * \post none
 * \sa none
**/
int msiDataObjAutoMove( msParam_t *inpParam1, msParam_t *inpParam2, msParam_t *inpParam3,
                        msParam_t *inpParam4, msParam_t *inpParam5, ruleExecInfo_t *rei ) {
    char *obj_path, *truct_path, *dest_coll, *new_owner;
    char *new_truct_path;
    char *new_obj_path;
    int  t;
    int  new_truct_path_len;
    rsComm_t *rsconn;
    char  mdest_coll[MAX_NAME_LEN];

    char  query_str[2048];
    genQueryInp_t genQueryInp;
    genQueryOut_t *genQueryOut = NULL;

    char new_obj_parent[MAX_NAME_LEN];
    char obj_name[MAX_NAME_LEN];

    collInp_t collCreateInp;
    dataObjCopyInp_t dataObjRenameInp;
    modAccessControlInp_t myModAccessCntlInp;

    dataObjInp_t myDataObjInp;
    char own_perm[20], null_perm[20];
    char user_name[NAME_LEN], zone_name[NAME_LEN];

    char *sTmpstr;
    int compute_checksum = 0;
    char *chksum_str = NULL;
    char tmpstr[1024];

    strcpy( own_perm, "own" );
    strcpy( null_perm, "null" );

    if ( rei == NULL || rei->rsComm == NULL ) {
        rodsLog( LOG_ERROR,
                 "msiDataObjAutoMove: input rei or rei->rsComm is NULL" );
        return ( SYS_INTERNAL_NULL_INPUT_ERR );
    }

    rsconn = rei->rsComm;

    if ( inpParam1 == NULL ) {
        rodsLog( LOG_ERROR, "msiDataObjAutoMove: input objpath (inpParam1) is NULL." );
        return SYS_INTERNAL_NULL_INPUT_ERR;
    }
    obj_path = ( char * )inpParam1->inOutStruct;
    if ( ( obj_path == NULL ) || ( strlen( obj_path ) == 0 ) ) {
        rodsLog( LOG_ERROR, "msiDataObjAutoMove: input objpath (inpParam1->inOutStruct) is NULL." );
        return SYS_INTERNAL_NULL_INPUT_ERR;
    }

    if ( inpParam2 == NULL ) {
        rodsLog( LOG_ERROR, "msiDataObjAutoMove: input truct_path (inpParam2) is NULL." );
        return SYS_INTERNAL_NULL_INPUT_ERR;
    }
    truct_path = ( char * )inpParam2->inOutStruct;
    if ( ( truct_path == NULL ) || ( strlen( truct_path ) == 0 ) ) {
        rodsLog( LOG_ERROR, "msiDataObjAutoMove: input truct_path (inpParam2->inOutStruct) is NULL." );
        return SYS_INTERNAL_NULL_INPUT_ERR;
    }

    if ( inpParam3 == NULL ) {
        rodsLog( LOG_ERROR, "msiDataObjAutoMove: input dest_coll (inpParam3) is NULL." );
        return SYS_INTERNAL_NULL_INPUT_ERR;
    }
    dest_coll = ( char * )inpParam3->inOutStruct;
    if ( ( dest_coll == NULL ) || ( strlen( dest_coll ) == 0 ) ) {
        rodsLog( LOG_ERROR, "msiDataObjAutoMove: input dest_coll (inpParam3->inOutStruct) is NULL." );
        return SYS_INTERNAL_NULL_INPUT_ERR;
    }

    if ( inpParam4 == NULL ) {
        rodsLog( LOG_ERROR, "msiDataObjAutoMove: input new_owner (inpParam4) is NULL." );
        return SYS_INTERNAL_NULL_INPUT_ERR;
    }
    new_owner = ( char * )inpParam4->inOutStruct;
    if ( new_owner != NULL ) {
        if ( strlen( new_owner ) == 0 ) {
            new_owner = NULL;
        }
        else if ( strcmp( new_owner, "null" ) == 0 ) {
            new_owner = NULL;
        }
    }
    if ( new_owner != NULL ) {
        user_name[0] = '\0';
        zone_name[0] = '\0';
        t = parseUserName( new_owner, user_name, zone_name );
        if ( t < 0 ) {
            rodsLog( LOG_ERROR, "msiDataObjAutoMove: parseUserName() failed. errStatus=%d.", t );
            return t;
        }
        if ( strlen( zone_name ) == 0 ) {
            strcpy( zone_name, rei->uoip->rodsZone );
        }
    }

    if ( inpParam5 == NULL ) {
        rodsLog( LOG_ERROR, "msiDataObjAutoMove: input compute_checksum (inpParam5) is NULL." );
        return SYS_INTERNAL_NULL_INPUT_ERR;
    }
    sTmpstr = ( char * )inpParam5->inOutStruct;
    compute_checksum = 1;   /* default to true */
    if ( ( sTmpstr != NULL ) && ( strlen( sTmpstr ) >= 0 ) ) {
        if ( strcmp( sTmpstr, "false" ) == 0 ) {
            compute_checksum = 0;
        }
    }

    if ( compute_checksum == 1 ) {
        chksum_str =  NULL;
        memset( &myDataObjInp, 0, sizeof( dataObjInp_t ) );
        strncpy( myDataObjInp.objPath, obj_path, MAX_NAME_LEN );
        addKeyVal( &myDataObjInp.condInput, VERIFY_CHKSUM_KW, "" );
        sprintf( tmpstr, "%d", 0 );
        addKeyVal( &myDataObjInp.condInput, REPL_NUM_KW, tmpstr );
        t = rsDataObjChksum( rsconn, &myDataObjInp, &chksum_str );
        if ( t < 0 ) {
            rodsLog( LOG_ERROR, "msiDataObjAutoMove: rsDataObjChksum() for '%s' failed. errStatus=%d.", obj_path, t );
            return t;
        }
    }

    if ( new_owner != NULL ) {
        /* add ownership */
        memset( &myModAccessCntlInp, 0, sizeof( modAccessControlInp_t ) );
        myModAccessCntlInp.recursiveFlag = False;
        myModAccessCntlInp.accessLevel = own_perm;
        myModAccessCntlInp.userName = user_name;
        myModAccessCntlInp.zone = zone_name;
        myModAccessCntlInp.path = obj_path;
        t = rsModAccessControl( rsconn, &myModAccessCntlInp );
        if ( t < 0 ) {
            rodsLog( LOG_ERROR, "msiDataObjAutoMove: rsModAccessControl() add new owner for '%s' failed. errStatus=%d.", obj_path, t );
            return t;
        }

    }

    t = strlen( truct_path );
    new_truct_path = ( char * )calloc( t + 2, sizeof( char ) );
    if ( truct_path[t - 1] != '/' ) {
        strcpy( new_truct_path, truct_path );
        new_truct_path_len = t;
    }
    else {
        strcpy( new_truct_path, truct_path );
        new_truct_path[t] = '/';
        new_truct_path[t + 1] = '\0';
        new_truct_path_len = t + 1;
    }
    if ( strncmp( new_truct_path, obj_path, t ) != 0 ) {
        /* when the object is not match, we don't move */
        rodsLog( LOG_ERROR, "msiDataObjAutoMove: The object path, %s, is not in the specified collection, %s.", obj_path, new_truct_path );
        return SYS_INTERNAL_NULL_INPUT_ERR;
    }

    t = strlen( dest_coll );
    new_obj_path = ( char * )calloc( t + strlen( obj_path ), sizeof( char ) );
    strcpy( mdest_coll, dest_coll );
    if ( dest_coll[t - 1] == '/' ) {
        mdest_coll[t - 1] = '\0';
    }
    sprintf( new_obj_path, "%s/%s", mdest_coll, &( obj_path[new_truct_path_len + 1] ) );
    sprintf( query_str, "SELECT COLL_NAME WHERE COLL_NAME like '%s%%'", mdest_coll );

    /* check if the dest_coll exists */
    memset( &genQueryInp, 0, sizeof( genQueryInp_t ) );
    t = fillGenQueryInpFromStrCond( query_str, &genQueryInp );
    if ( t < 0 ) {
        rodsLog( LOG_ERROR, "msiDataObjAutoMove: fillGenQueryInpFromStrCond() failed. errStatus=%d", t );
        free( new_obj_path ); // JMC cppcheck - leak
        free( new_truct_path ); // JMC cppcheck - leak
        return t;
    }
    genQueryInp.maxRows = MAX_SQL_ROWS;
    genQueryInp.continueInx = 0;
    t = rsGenQuery( rsconn, &genQueryInp, &genQueryOut );
    if ( t < 0 ) {
        if ( t == CAT_NO_ROWS_FOUND ) {
            rodsLog( LOG_ERROR, "msiDataObjAutoMove: The destination collection '%s' does not exist.", dest_coll );
        }
        else {
            rodsLog( LOG_ERROR, "msiDataObjAutoMove: rsGenQuery() failed. errStatus=%d", t );
        }
        free( new_obj_path ); // JMC cppcheck - leak
        free( new_truct_path ); // JMC cppcheck - leak
        return t;
    }

    /* separate new_obj_path with path and name */
    t = splitPathByKey( new_obj_path, new_obj_parent, obj_name, '/' );
    if ( t < 0 ) {
        rodsLog( LOG_ERROR, "msiDataObjAutoMove: splitPathByKey() failed for splitting '%s'. errStatus=%d.", new_obj_path, t );
        free( new_obj_path ); // JMC cppcheck - leak
        free( new_truct_path ); // JMC cppcheck - leak
        return t;
    }

    /* fprintf(stderr,"msiDataObjAutoMove: newpar=%s, obj_name=%s, from=%s\n", new_obj_parent, obj_name, obj_path); */

    /* create the dires in new_obj_path 'imkidr -p'*/
    if ( strlen( new_obj_parent ) > strlen( mdest_coll ) ) {
        memset( &collCreateInp, 0, sizeof( collCreateInp ) );
        rstrcpy( collCreateInp.collName, new_obj_parent, MAX_NAME_LEN );
        addKeyVal( &collCreateInp.condInput, RECURSIVE_OPR__KW, "" );   /* always have '-p' option. */
        t = rsCollCreate( rsconn, &collCreateInp );
        if ( t < 0 ) {
            rodsLog( LOG_ERROR, "msiDataObjAutoMove: rsCollCreate() failed for %s. errStatus=%d.", new_obj_parent, t );
            free( new_obj_path ); // JMC cppcheck - leak
            free( new_truct_path ); // JMC cppcheck - leak
            return t;
        }
    }

    fprintf( stderr, "new_obj_path=%s, obj_path=%s\n", new_obj_path, obj_path );
    /* renamed the obj_path to new_obj_path */
    memset( &dataObjRenameInp, 0, sizeof( dataObjCopyInp_t ) );
    rstrcpy( dataObjRenameInp.destDataObjInp.objPath, new_obj_path, MAX_NAME_LEN );
    rstrcpy( dataObjRenameInp.srcDataObjInp.objPath, obj_path, MAX_NAME_LEN );
    t = rsDataObjRename( rsconn, &dataObjRenameInp );
    if ( t < 0 ) {
        rodsLog( LOG_ERROR, "msiDataObjAutoMove: rsDataObjRename() failed. errStatus=%d.", t );
        free( new_obj_path ); // JMC cppcheck - leak
        free( new_truct_path ); // JMC cppcheck - leak
        return t;
    }

    memset( &myModAccessCntlInp, 0, sizeof( modAccessControlInp_t ) );
    myModAccessCntlInp.recursiveFlag = False;
    myModAccessCntlInp.accessLevel = null_perm;
    myModAccessCntlInp.userName = rei->uoic->userName;
    myModAccessCntlInp.zone = zone_name;
    myModAccessCntlInp.path = new_obj_path;
    t = rsModAccessControl( rsconn, &myModAccessCntlInp );
    if ( t < 0 ) {
        rodsLog( LOG_ERROR, "msiDataObjAutoMove: rsModAccessControl() remove user for '%s' failed. errStatus=%d.", obj_path, t );
    }

    free( new_truct_path ); // JMC cppcheck - leak
    return 0;
}