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; }
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); }
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); }
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; }