int rsOpenCollection( rsComm_t *rsComm, collInp_t *openCollInp ) { int status; int handleInx; collHandle_t *collHandle; 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 ); } rodsObjStat_t *rodsObjStatOut = NULL; status = rsObjStat( rsComm, &collHandle->dataObjInp, &rodsObjStatOut ); if ( status < 0 ) { freeRodsObjStat( rodsObjStatOut ); rsCloseCollection( rsComm, &handleInx ); return status; } if ( rodsObjStatOut->objType != COLL_OBJ_T ) { freeRodsObjStat( rodsObjStatOut ); rsCloseCollection( rsComm, &handleInx ); return CAT_NAME_EXISTS_AS_DATAOBJ; } replSpecColl( rodsObjStatOut->specColl, &collHandle->dataObjInp.specColl ); 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; }
/** * @brief getatt_aux Fills a fattr3_atributes with iRODS object attributes. * Unfortunately only two attributes were possible to be mapped, until now. * @param comm Connection variable * @param path Path to the corresponding object (directory or file) * @param fattr3_atributes * * Example of use: * fattr3 fattr3_atributes; rcComm_t* comm = rodsConnect(); int i = rodsLogin(comm); char* path = "tempZone/home/desiredFile.txt"); getatt_aux(comm, path, &fattr3_atributes); printf("Type: %d\n", fattr3_atributes.type); printf("Size: %d\n", fattr3_atributes.size); */ int getatt_aux(nfs_fh3 fh, fattr3 fat, rcComm_t* comm, char *path, int *size) { dataObjInp_t dataObjInp; rodsObjStat_t *rodsObjStatOut = NULL; bzero (&dataObjInp, sizeof (dataObjInp)); rstrcpy (dataObjInp.objPath, path, MAX_NAME_LEN); int status = rcObjStat (comm, &dataObjInp, &rodsObjStatOut); if (status < 0) { debug("GETATT - Error - The call to iRODS was unsuccessful searching the file %s.\n", path); } else { *size = rodsObjStatOut->objSize; /*It is necessary to change the attributes locally (executing a SETATT) * to avoid the NFS Stale File Handle error.*/ set_aux(fh, fat, path, size); } return status; freeRodsObjStat (rodsObjStatOut); }
static void _keepAlive(iFuseConn_t *iFuseConn) { int status = 0; char iRodsPath[MAX_NAME_LEN]; dataObjInp_t dataObjInp; rodsObjStat_t *rodsObjStatOut = NULL; bzero(iRodsPath, MAX_NAME_LEN); status = iFuseRodsClientMakeRodsPath("/", iRodsPath); if (status < 0) { iFuseRodsClientLogError(LOG_ERROR, status, "_keepAlive: iFuseRodsClientMakeRodsPath of %s error", iRodsPath); return; } iFuseRodsClientLog(LOG_DEBUG, "_keepAlive: %s", iRodsPath); bzero(&dataObjInp, sizeof ( dataObjInp_t)); rstrcpy(dataObjInp.objPath, iRodsPath, MAX_NAME_LEN); iFuseConnLock(iFuseConn); status = iFuseRodsClientObjStat(iFuseConn->conn, &dataObjInp, &rodsObjStatOut); if (status < 0) { iFuseRodsClientLogError(LOG_ERROR, status, "_keepAlive: iFuseRodsClientObjStat of %s error, status = %d", iRodsPath, status); iFuseConnUnlock(iFuseConn); return; } if(rodsObjStatOut != NULL) { freeRodsObjStat(rodsObjStatOut); } iFuseConnUnlock(iFuseConn); }
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); }
int unmountFileDir (rsComm_t *rsComm, dataObjInp_t *phyPathRegInp) { int status; collInp_t modCollInp; rodsObjStat_t *rodsObjStatOut = NULL; status = collStat (rsComm, phyPathRegInp, &rodsObjStatOut); if (status < 0) { return status; } else if (rodsObjStatOut->specColl == NULL) { freeRodsObjStat (rodsObjStatOut); rodsLog (LOG_ERROR, "unmountFileDir: %s not mounted", phyPathRegInp->objPath); return (SYS_COLL_NOT_MOUNTED_ERR); } if (getStructFileType (rodsObjStatOut->specColl) >= 0) { /* a struct file */ status = _rsSyncMountedColl (rsComm, rodsObjStatOut->specColl, PURGE_STRUCT_FILE_CACHE); #if 0 if (status < 0) { freeRodsObjStat (rodsObjStatOut); return (status); } #endif } freeRodsObjStat (rodsObjStatOut); memset (&modCollInp, 0, sizeof (modCollInp)); rstrcpy (modCollInp.collName, phyPathRegInp->objPath, MAX_NAME_LEN); addKeyVal (&modCollInp.condInput, COLLECTION_TYPE_KW, "NULL_SPECIAL_VALUE"); addKeyVal (&modCollInp.condInput, COLLECTION_INFO1_KW, "NULL_SPECIAL_VALUE"); addKeyVal (&modCollInp.condInput, COLLECTION_INFO2_KW, "NULL_SPECIAL_VALUE"); status = rsModColl (rsComm, &modCollInp); return (status); }
int rsSyncMountedColl (rsComm_t *rsComm, dataObjInp_t *syncMountedCollInp) { int status; rodsObjStat_t *rodsObjStatOut = NULL; dataObjInp_t myDataObjInp; int remoteFlag; rodsServerHost_t *rodsServerHost; status = collStat (rsComm, syncMountedCollInp, &rodsObjStatOut); if (status < 0) return status; if (rodsObjStatOut->specColl == NULL) { freeRodsObjStat (rodsObjStatOut); rodsLog (LOG_ERROR, "rsSyncMountedColl: %s not a mounted collection", syncMountedCollInp->objPath); return (SYS_COLL_NOT_MOUNTED_ERR); } bzero (&myDataObjInp, sizeof (myDataObjInp)); rstrcpy (myDataObjInp.objPath, rodsObjStatOut->specColl->objPath, MAX_NAME_LEN); remoteFlag = getAndConnRemoteZone (rsComm, &myDataObjInp, &rodsServerHost, REMOTE_OPEN); if (remoteFlag < 0) { return (remoteFlag); } else if (remoteFlag == REMOTE_HOST) { status = rcSyncMountedColl (rodsServerHost->conn, syncMountedCollInp); } else { status = _rsSyncMountedColl (rsComm, rodsObjStatOut->specColl, syncMountedCollInp->oprType); } freeRodsObjStat (rodsObjStatOut); return (status); }
void clearRodsPath( rodsPath_t *rodsPath ) { if ( rodsPath == NULL ) { return; } if ( rodsPath->rodsObjStat == NULL ) { return; } freeRodsObjStat( rodsPath->rodsObjStat ); memset( rodsPath, 0, sizeof( rodsPath_t ) ); return; }
int isCollAllKinds( rsComm_t *rsComm, char *objName, rodsLong_t *collId ) { dataObjInp_t dataObjInp; int status; rodsObjStat_t *rodsObjStatOut = NULL; bzero( &dataObjInp, sizeof( dataObjInp ) ); rstrcpy( dataObjInp.objPath, objName, MAX_NAME_LEN ); status = collStatAllKinds( rsComm, &dataObjInp, &rodsObjStatOut ); if ( status >= 0 && collId != NULL && NULL != rodsObjStatOut ) { // JMC cppcheck - nullptr *collId = strtoll( rodsObjStatOut->dataId, 0, 0 ); } if ( rodsObjStatOut != NULL ) { freeRodsObjStat( rodsObjStatOut ); } return status; }
void clearRodsPath (rodsPath_t *rodsPath) { if (rodsPath == NULL) return; if (rodsPath->rodsObjStat == NULL) return; #if 0 /* this is freed in freeRodsObjStat */ if (rodsPath->rodsObjStat->specColl != NULL) free (rodsPath->rodsObjStat->specColl); #endif freeRodsObjStat (rodsPath->rodsObjStat); memset (rodsPath, 0, sizeof (rodsPath_t)); return; }
int collStatAllKinds( rsComm_t *rsComm, dataObjInp_t *dataObjInp, rodsObjStat_t **rodsObjStatOut ) { int status; *rodsObjStatOut = NULL; addKeyVal( &dataObjInp->condInput, SEL_OBJ_TYPE_KW, "collection" ); status = _rsObjStat( rsComm, dataObjInp, rodsObjStatOut ); rmKeyVal( &dataObjInp->condInput, SEL_OBJ_TYPE_KW ); if ( status >= 0 ) { if ( ( *rodsObjStatOut )->objType != COLL_OBJ_T ) { status = OBJ_PATH_DOES_NOT_EXIST; } } if ( status < 0 && *rodsObjStatOut != NULL ) { freeRodsObjStat( *rodsObjStatOut ); *rodsObjStatOut = NULL; } return status; }
int specCollSubStat( rsComm_t *rsComm, specColl_t *specColl, char *subPath, specCollPerm_t specCollPerm, dataObjInfo_t **dataObjInfo ) { int status; int objType; rodsStat_t *rodsStat = NULL; dataObjInfo_t *myDataObjInfo = NULL;; if ( dataObjInfo == NULL ) { return USER__NULL_INPUT_ERR; } *dataObjInfo = NULL; if ( specColl->collClass == MOUNTED_COLL ) { /* a mount point */ myDataObjInfo = *dataObjInfo = ( dataObjInfo_t * ) malloc( sizeof( dataObjInfo_t ) ); memset( myDataObjInfo, 0, sizeof( dataObjInfo_t ) ); /*status = resolveResc (specColl->resource, &myDataObjInfo->rescInfo); if (status < 0) { rodsLog( LOG_ERROR,"specCollSubStat: resolveResc error for %s, status = %d", specColl->resource, status); freeDataObjInfo (myDataObjInfo); *dataObjInfo = NULL; return status; }*/ rstrcpy( myDataObjInfo->objPath, subPath, MAX_NAME_LEN ); rstrcpy( myDataObjInfo->subPath, subPath, MAX_NAME_LEN ); rstrcpy( myDataObjInfo->rescName, specColl->resource, NAME_LEN ); rstrcpy( myDataObjInfo->rescHier, specColl->rescHier, MAX_NAME_LEN ); rstrcpy( myDataObjInfo->dataType, "generic", NAME_LEN ); status = getMountedSubPhyPath( specColl->collection, specColl->phyPath, subPath, myDataObjInfo->filePath ); if ( status < 0 ) { freeDataObjInfo( myDataObjInfo ); *dataObjInfo = NULL; return status; } replSpecColl( specColl, &myDataObjInfo->specColl ); } else if ( specColl->collClass == LINKED_COLL ) { /* a link point */ specCollCache_t *specCollCache = NULL; char newPath[MAX_NAME_LEN]; specColl_t *curSpecColl; char *accessStr; dataObjInp_t myDataObjInp; rodsObjStat_t *rodsObjStatOut = NULL; *dataObjInfo = NULL; curSpecColl = specColl; status = getMountedSubPhyPath( curSpecColl->collection, curSpecColl->phyPath, subPath, newPath ); if ( status < 0 ) { return status; } status = resolveLinkedPath( rsComm, newPath, &specCollCache, NULL ); if ( status < 0 ) { return status; } if ( specCollCache != NULL && specCollCache->specColl.collClass != LINKED_COLL ) { status = specCollSubStat( rsComm, &specCollCache->specColl, newPath, specCollPerm, dataObjInfo ); return status; } bzero( &myDataObjInp, sizeof( myDataObjInp ) ); rstrcpy( myDataObjInp.objPath, newPath, MAX_NAME_LEN ); status = collStat( rsComm, &myDataObjInp, &rodsObjStatOut ); if ( status >= 0 && NULL != rodsObjStatOut ) { /* a collection */ // JMC cppcheck - nullptr myDataObjInfo = *dataObjInfo = ( dataObjInfo_t * ) malloc( sizeof( dataObjInfo_t ) ); memset( myDataObjInfo, 0, sizeof( dataObjInfo_t ) ); replSpecColl( curSpecColl, &myDataObjInfo->specColl ); rstrcpy( myDataObjInfo->objPath, newPath, MAX_NAME_LEN ); myDataObjInfo->dataId = strtoll( rodsObjStatOut->dataId, 0, 0 ); rstrcpy( myDataObjInfo->dataOwnerName, rodsObjStatOut->ownerName, NAME_LEN ); rstrcpy( myDataObjInfo->dataOwnerZone, rodsObjStatOut->ownerZone, NAME_LEN ); rstrcpy( myDataObjInfo->dataCreate, rodsObjStatOut->createTime, TIME_LEN ); rstrcpy( myDataObjInfo->dataModify, rodsObjStatOut->modifyTime, TIME_LEN ); freeRodsObjStat( rodsObjStatOut ); return COLL_OBJ_T; } freeRodsObjStat( rodsObjStatOut ); /* data object */ if ( specCollPerm == READ_COLL_PERM ) { accessStr = ACCESS_READ_OBJECT; } else if ( specCollPerm == WRITE_COLL_PERM ) { accessStr = ACCESS_DELETE_OBJECT; } else { accessStr = NULL; } status = getDataObjInfo( rsComm, &myDataObjInp, dataObjInfo, accessStr, 0 ); if ( status < 0 ) { myDataObjInfo = *dataObjInfo = ( dataObjInfo_t * ) malloc( sizeof( dataObjInfo_t ) ); memset( myDataObjInfo, 0, sizeof( dataObjInfo_t ) ); replSpecColl( curSpecColl, &myDataObjInfo->specColl ); rstrcpy( myDataObjInfo->objPath, newPath, MAX_NAME_LEN ); rodsLog( LOG_DEBUG, "specCollSubStat: getDataObjInfo error for %s, status = %d", newPath, status ); return status; } else { replSpecColl( curSpecColl, &( *dataObjInfo )->specColl ); return DATA_OBJ_T; } } else if ( getStructFileType( specColl ) >= 0 ) { /* bundle */ dataObjInp_t myDataObjInp; dataObjInfo_t *tmpDataObjInfo; bzero( &myDataObjInp, sizeof( myDataObjInp ) ); rstrcpy( myDataObjInp.objPath, specColl->objPath, MAX_NAME_LEN ); // add the resource hierarchy to the condInput of the inp addKeyVal( &myDataObjInp.condInput, RESC_HIER_STR_KW, specColl->rescHier ); status = getDataObjInfo( rsComm, &myDataObjInp, dataObjInfo, NULL, 1 ); if ( status < 0 ) { rodsLog( LOG_ERROR, "specCollSubStat: getDataObjInfo error for %s, status = %d", myDataObjInp.objPath, status ); *dataObjInfo = NULL; return status; } /* screen out any stale copies */ status = sortObjInfoForOpen( dataObjInfo, &myDataObjInp.condInput, 0 ); if ( status < 0 ) { rodsLog( LOG_ERROR, "specCollSubStat: sortObjInfoForOpen error for %s. status = %d", myDataObjInp.objPath, status ); return status; } if ( strlen( specColl->resource ) > 0 ) { if ( requeDataObjInfoByResc( dataObjInfo, specColl->resource, 0, 1 ) >= 0 ) { if ( strcmp( specColl->resource, ( *dataObjInfo )->rescName ) != 0 ) { rodsLog( LOG_ERROR, "specCollSubStat: %s in %s does not match cache resc %s", myDataObjInp.objPath, ( *dataObjInfo )->rescName, specColl->resource ); freeAllDataObjInfo( *dataObjInfo ); *dataObjInfo = NULL; return SYS_CACHE_STRUCT_FILE_RESC_ERR; } } else { rodsLog( LOG_ERROR, "specCollSubStat: requeDataObjInfoByResc %s, resc %s error", myDataObjInp.objPath, specColl->resource ); freeAllDataObjInfo( *dataObjInfo ); *dataObjInfo = NULL; return SYS_CACHE_STRUCT_FILE_RESC_ERR; } } /* free all the other dataObjInfo */ if ( ( *dataObjInfo )->next != NULL ) { freeAllDataObjInfo( ( *dataObjInfo )->next ); ( *dataObjInfo )->next = NULL; } /* fill in DataObjInfo */ tmpDataObjInfo = *dataObjInfo; replSpecColl( specColl, &tmpDataObjInfo->specColl ); rstrcpy( specColl->resource, tmpDataObjInfo->rescName, NAME_LEN ); rstrcpy( specColl->rescHier, tmpDataObjInfo->rescHier, MAX_NAME_LEN ); rstrcpy( specColl->phyPath, tmpDataObjInfo->filePath, MAX_NAME_LEN ); rstrcpy( tmpDataObjInfo->subPath, subPath, MAX_NAME_LEN ); specColl->replNum = tmpDataObjInfo->replNum; if ( strcmp( ( *dataObjInfo )->subPath, specColl->collection ) == 0 ) { /* no need to go down */ return COLL_OBJ_T; } } else { rodsLog( LOG_ERROR, "specCollSubStat: Unknown specColl collClass = %d", specColl->collClass ); return SYS_UNKNOWN_SPEC_COLL_CLASS; } status = l3Stat( rsComm, *dataObjInfo, &rodsStat ); if ( status < 0 ) { return status; } if ( rodsStat->st_ctim != 0 ) { snprintf( ( *dataObjInfo )->dataCreate, TIME_LEN, "%d", rodsStat->st_ctim ); snprintf( ( *dataObjInfo )->dataModify, TIME_LEN, "%d", rodsStat->st_mtim ); } if ( rodsStat->st_mode & S_IFDIR ) { objType = COLL_OBJ_T; } else { objType = DATA_OBJ_T; ( *dataObjInfo )->dataSize = rodsStat->st_size; } free( rodsStat ); return objType; }
int structFileReg (rsComm_t *rsComm, dataObjInp_t *phyPathRegInp) { collInp_t collCreateInp; int status; dataObjInfo_t *dataObjInfo = NULL; char *structFilePath = NULL; dataObjInp_t dataObjInp; char *collType; int len; rodsObjStat_t *rodsObjStatOut = NULL; specCollCache_t *specCollCache = NULL; rescInfo_t *rescInfo = NULL; #if 0 /* fixed */ /* make it a privileged call for now */ if (rsComm->clientUser.authInfo.authFlag < LOCAL_PRIV_USER_AUTH) return(CAT_INSUFFICIENT_PRIVILEGE_LEVEL); #endif if ((structFilePath = getValByKey (&phyPathRegInp->condInput, FILE_PATH_KW)) == NULL) { rodsLog (LOG_ERROR, "structFileReg: No structFilePath input for %s", phyPathRegInp->objPath); return (SYS_INVALID_FILE_PATH); } collType = getValByKey (&phyPathRegInp->condInput, COLLECTION_TYPE_KW); if (collType == NULL) { rodsLog (LOG_ERROR, "structFileReg: Bad COLLECTION_TYPE_KW for structFilePath %s", dataObjInp.objPath); return (SYS_INTERNAL_NULL_INPUT_ERR); } len = strlen (phyPathRegInp->objPath); if (strncmp (structFilePath, phyPathRegInp->objPath, len) == 0 && (structFilePath[len] == '\0' || structFilePath[len] == '/')) { rodsLog (LOG_ERROR, "structFileReg: structFilePath %s inside collection %s", structFilePath, phyPathRegInp->objPath); return (SYS_STRUCT_FILE_INMOUNTED_COLL); } /* see if the struct file is in spec coll */ if (getSpecCollCache (rsComm, structFilePath, 0, &specCollCache) >= 0) { rodsLog (LOG_ERROR, "structFileReg: structFilePath %s is in a mounted path", structFilePath); return (SYS_STRUCT_FILE_INMOUNTED_COLL); } status = collStat (rsComm, phyPathRegInp, &rodsObjStatOut); if (status < 0) return status; if (rodsObjStatOut->specColl != NULL) { freeRodsObjStat (rodsObjStatOut); rodsLog (LOG_ERROR, "structFileReg: %s already mounted", phyPathRegInp->objPath); return (SYS_MOUNT_MOUNTED_COLL_ERR); } freeRodsObjStat (rodsObjStatOut); if (isCollEmpty (rsComm, phyPathRegInp->objPath) == False) { rodsLog (LOG_ERROR, "structFileReg: collection %s not empty", phyPathRegInp->objPath); return (SYS_COLLECTION_NOT_EMPTY); } memset (&dataObjInp, 0, sizeof (dataObjInp)); rstrcpy (dataObjInp.objPath, structFilePath, sizeof (dataObjInp)); /* user need to have write permission */ dataObjInp.openFlags = O_WRONLY; status = getDataObjInfoIncSpecColl (rsComm, &dataObjInp, &dataObjInfo); if (status < 0) { int myStatus; /* try to make one */ dataObjInp.condInput = phyPathRegInp->condInput; /* have to remove FILE_PATH_KW because getFullPathName will use it */ rmKeyVal (&dataObjInp.condInput, FILE_PATH_KW); myStatus = rsDataObjCreate (rsComm, &dataObjInp); if (myStatus < 0) { rodsLog (LOG_ERROR, "structFileReg: Problem with open/create structFilePath %s, status = %d", dataObjInp.objPath, status); return (status); } else { openedDataObjInp_t dataObjCloseInp; bzero (&dataObjCloseInp, sizeof (dataObjCloseInp)); rescInfo = L1desc[myStatus].dataObjInfo->rescInfo; dataObjCloseInp.l1descInx = myStatus; rsDataObjClose (rsComm, &dataObjCloseInp); } } else { rescInfo = dataObjInfo->rescInfo; } if (!structFileSupport (rsComm, phyPathRegInp->objPath, collType, rescInfo)) { rodsLog (LOG_ERROR, "structFileReg: structFileDriver type %s does not exist for %s", collType, dataObjInp.objPath); return (SYS_NOT_SUPPORTED); } /* mk the collection */ memset (&collCreateInp, 0, sizeof (collCreateInp)); rstrcpy (collCreateInp.collName, phyPathRegInp->objPath, MAX_NAME_LEN); addKeyVal (&collCreateInp.condInput, COLLECTION_TYPE_KW, collType); /* have to use dataObjInp.objPath because structFile path was removed */ addKeyVal (&collCreateInp.condInput, COLLECTION_INFO1_KW, dataObjInp.objPath); /* try to mod the coll first */ status = rsModColl (rsComm, &collCreateInp); if (status < 0) { /* try to create it */ status = rsRegColl (rsComm, &collCreateInp); } return (status); }
int rsyncDirToCollUtil (rcComm_t *conn, rodsPath_t *srcPath, rodsPath_t *targPath, rodsEnv *myRodsEnv, rodsArguments_t *rodsArgs, dataObjInp_t *dataObjOprInp) { int status = 0; int savedStatus = 0; #ifndef USE_BOOST_FS DIR *dirPtr; struct dirent *myDirent; #ifndef windows_platform struct stat statbuf; #else struct irodsntstat statbuf; #endif #endif /* #ifndef USE_BOOST_FS */ char *srcDir, *targColl; rodsPath_t mySrcPath, myTargPath; if (srcPath == NULL || targPath == NULL) { rodsLog (LOG_ERROR, "rsyncDirToCollUtil: NULL srcPath or targPath input"); return (USER__NULL_INPUT_ERR); } srcDir = srcPath->outPath; targColl = targPath->outPath; if (isPathSymlink (rodsArgs, srcDir) > 0) return 0; if (rodsArgs->recursive != True) { rodsLog (LOG_ERROR, "rsyncDirToCollUtil: -r option must be used for putting %s directory", srcDir); return (USER_INPUT_OPTION_ERR); } #ifdef USE_BOOST_FS path srcDirPath (srcDir); if (!exists(srcDirPath) || !is_directory(srcDirPath)) { #else dirPtr = opendir (srcDir); if (dirPtr == NULL) { #endif /* USE_BOOST_FS */ rodsLog (LOG_ERROR, "rsyncDirToCollUtil: opendir local dir error for %s, errno = %d\n", srcDir, errno); return (USER_INPUT_PATH_ERR); } if (rodsArgs->verbose == True) { fprintf (stdout, "C- %s:\n", targColl); } memset (&mySrcPath, 0, sizeof (mySrcPath)); memset (&myTargPath, 0, sizeof (myTargPath)); myTargPath.objType = DATA_OBJ_T; mySrcPath.objType = LOCAL_FILE_T; #ifdef USE_BOOST_FS directory_iterator end_itr; // default construction yields past-the-end for (directory_iterator itr(srcDirPath); itr != end_itr;++itr) { path p = itr->path(); snprintf (mySrcPath.outPath, MAX_NAME_LEN, "%s", p.c_str ()); #else while ((myDirent = readdir (dirPtr)) != NULL) { if (strcmp (myDirent->d_name, ".") == 0 || strcmp (myDirent->d_name, "..") == 0) { continue; } snprintf (mySrcPath.outPath, MAX_NAME_LEN, "%s/%s", srcDir, myDirent->d_name); #endif /* USE_BOOST_FS */ if (isPathSymlink (rodsArgs, mySrcPath.outPath) > 0) continue; #ifdef USE_BOOST_FS #if 0 path p (mySrcPath.outPath); #endif if (!exists(p)) { #else #ifndef windows_platform status = stat (mySrcPath.outPath, &statbuf); #else status = iRODSNt_stat(mySrcPath.outPath, &statbuf); #endif if (status != 0) { closedir (dirPtr); #endif /* USE_BOOST_FS */ rodsLog (LOG_ERROR, "rsyncDirToCollUtil: stat error for %s, errno = %d\n", mySrcPath.outPath, errno); return (USER_INPUT_PATH_ERR); } #ifndef USE_BOOST_FS if ((statbuf.st_mode & S_IFREG) != 0 && rodsArgs->age == True) { if (ageExceeded (rodsArgs->agevalue, statbuf.st_mtime, rodsArgs->verbose, mySrcPath.outPath, statbuf.st_size)) continue; } #endif /* #ifndef USE_BOOST_FS */ #ifdef FILESYSTEM_META getFileMetaFromPath(mySrcPath.outPath, &dataObjOprInp->condInput); #endif bzero (&myTargPath, sizeof (myTargPath)); #ifdef USE_BOOST_FS path childPath = p.filename(); snprintf (myTargPath.outPath, MAX_NAME_LEN, "%s/%s", targColl, childPath.c_str()); if (is_symlink (p)) { path cp = read_symlink (p); snprintf (mySrcPath.outPath, MAX_NAME_LEN, "%s/%s", srcDir, cp.c_str ()); p = path (mySrcPath.outPath); } dataObjOprInp->createMode = getPathStMode (p); if (is_regular_file(p)) { #else snprintf (myTargPath.outPath, MAX_NAME_LEN, "%s/%s", targColl, myDirent->d_name); dataObjOprInp->createMode = statbuf.st_mode; if ((statbuf.st_mode & S_IFREG) != 0) { /* a file */ #endif myTargPath.objType = DATA_OBJ_T; mySrcPath.objType = LOCAL_FILE_T; mySrcPath.objState = EXIST_ST; #ifdef USE_BOOST_FS mySrcPath.size = file_size (p); #else mySrcPath.size = statbuf.st_size; #endif getRodsObjType (conn, &myTargPath); status = rsyncFileToDataUtil (conn, &mySrcPath, &myTargPath, myRodsEnv, rodsArgs, dataObjOprInp); /* fix a big mem leak */ if (myTargPath.rodsObjStat != NULL) { freeRodsObjStat (myTargPath.rodsObjStat); myTargPath.rodsObjStat = NULL; } #if 0 if (myTargPath.objState != NOT_EXIST_ST) freeRodsObjStat (myTargPath.rodsObjStat); #endif #ifdef USE_BOOST_FS } else if (is_directory(p)) { #else } else if ((statbuf.st_mode & S_IFDIR) != 0) { /* a directory */ #endif status = 0; /* only do the sync if no -l option specified */ if ( rodsArgs->longOption != True ) { #ifdef FILESYSTEM_META status = mkCollRWithDirMeta (conn, targColl, myTargPath.outPath, mySrcPath.outPath); #else status = mkCollR (conn, targColl, myTargPath.outPath); #endif } if (status < 0) { rodsLogError (LOG_ERROR, status, "rsyncDirToCollUtil: mkCollR error for %s", myTargPath.outPath); } else { myTargPath.objType = COLL_OBJ_T; mySrcPath.objType = LOCAL_DIR_T; mySrcPath.objState = myTargPath.objState = EXIST_ST; getRodsObjType (conn, &myTargPath); status = rsyncDirToCollUtil (conn, &mySrcPath, &myTargPath, myRodsEnv, rodsArgs, dataObjOprInp); /* fix a big mem leak */ if (myTargPath.rodsObjStat != NULL) { freeRodsObjStat (myTargPath.rodsObjStat); myTargPath.rodsObjStat = NULL; } #if 0 if (myTargPath.objState != NOT_EXIST_ST) freeRodsObjStat (myTargPath.rodsObjStat); #endif } } else { rodsLog (LOG_ERROR, #ifdef USE_BOOST_FS "rsyncDirToCollUtil: unknown local path %s", mySrcPath.outPath); #else "rsyncDirToCollUtil: unknown local path type %d for %s", statbuf.st_mode, mySrcPath.outPath); #endif /* USE_BOOST_FS */ status = USER_INPUT_PATH_ERR; } if (status < 0) { savedStatus = status; rodsLogError (LOG_ERROR, status, "rsyncDirToCollUtil: put %s failed. status = %d", mySrcPath.outPath, status); } } #ifndef USE_BOOST_FS closedir (dirPtr); #endif if (savedStatus < 0) { return (savedStatus); } else if (status == CAT_NO_ROWS_FOUND || status == SYS_SPEC_COLL_OBJ_NOT_EXIST) { return (0); } else { return (status); } } int rsyncCollToCollUtil (rcComm_t *conn, rodsPath_t *srcPath, rodsPath_t *targPath, rodsEnv *myRodsEnv, rodsArguments_t *rodsArgs, dataObjCopyInp_t *dataObjCopyInp) { int status = 0; int savedStatus = 0; char *srcColl, *targColl; char targChildPath[MAX_NAME_LEN]; #if 0 int collLen; #else char parPath[MAX_NAME_LEN], childPath[MAX_NAME_LEN]; #endif rodsPath_t mySrcPath, myTargPath; collHandle_t collHandle; collEnt_t collEnt; dataObjCopyInp_t childDataObjCopyInp; dataObjInp_t *dataObjOprInp = &collHandle.dataObjInp; if (srcPath == NULL || targPath == NULL) { rodsLog (LOG_ERROR, "rsyncCollToCollUtil: NULL srcPath or targPath input"); return (USER__NULL_INPUT_ERR); } srcColl = srcPath->outPath; targColl = targPath->outPath; if (rodsArgs->recursive != True) { rodsLog (LOG_ERROR, "rsyncCollToCollUtil: -r option must be used for collection %s", targColl); return (USER_INPUT_OPTION_ERR); } #if 0 status = rclOpenCollection (conn, srcColl, RECUR_QUERY_FG | VERY_LONG_METADATA_FG, &collHandle); #else status = rclOpenCollection (conn, srcColl, VERY_LONG_METADATA_FG, &collHandle); #endif if (status < 0) { rodsLog (LOG_ERROR, "getCollUtil: rclOpenCollection of %s error. status = %d", srcColl, status); return status; } if (dataObjOprInp->specColl != NULL) { if (rodsArgs->verbose == True) { if (rodsArgs->verbose == True) { char objType[NAME_LEN]; status = getSpecCollTypeStr (dataObjOprInp->specColl, objType); if (status < 0) fprintf (stdout, "C- %s :\n", targColl); else fprintf (stdout, "C- %s %-5.5s :\n", targColl, objType); } } } memset (&mySrcPath, 0, sizeof (mySrcPath)); memset (&myTargPath, 0, sizeof (myTargPath)); myTargPath.objType = DATA_OBJ_T; mySrcPath.objType = DATA_OBJ_T; #if 0 collLen = strlen (srcColl); collLen = getOpenedCollLen (&collHandle); #endif while ((status = rclReadCollection (conn, &collHandle, &collEnt)) >= 0) { if (collEnt.objType == DATA_OBJ_T) { if (rodsArgs->age == True) { if (ageExceeded (rodsArgs->agevalue, atoi (collEnt.modifyTime), rodsArgs->verbose, collEnt.dataName, collEnt.dataSize)) continue; } #if 0 snprintf (myTargPath.outPath, MAX_NAME_LEN, "%s%s/%s", targColl, collEnt.collName + collLen, collEnt.dataName); #else snprintf (myTargPath.outPath, MAX_NAME_LEN, "%s/%s", targColl, collEnt.dataName); #endif snprintf (mySrcPath.outPath, MAX_NAME_LEN, "%s/%s", collEnt.collName, collEnt.dataName); /* fill in some info for mySrcPath */ if (strlen (mySrcPath.dataId) == 0) rstrcpy (mySrcPath.dataId, collEnt.dataId, NAME_LEN); mySrcPath.size = collEnt.dataSize; rstrcpy (mySrcPath.chksum, collEnt.chksum, CHKSUM_LEN); mySrcPath.objState = EXIST_ST; #if 0 getFileType (&myTargPath); #else getRodsObjType (conn, &myTargPath); #endif status = rsyncDataToDataUtil (conn, &mySrcPath, &myTargPath, myRodsEnv, rodsArgs, dataObjCopyInp); if (myTargPath.rodsObjStat != NULL) { freeRodsObjStat (myTargPath.rodsObjStat); myTargPath.rodsObjStat = NULL; } if (status < 0) { rodsLogError (LOG_ERROR, status, "rsyncCollToCollUtil: rsyncDataToDataUtil failed for %s.stat=%d", myTargPath.outPath, status); /* need to set global error here */ savedStatus = status; status = 0; } } else if (collEnt.objType == COLL_OBJ_T) { #if 0 if (strlen (collEnt.collName) <= collLen) continue; snprintf (targChildPath, MAX_NAME_LEN, "%s%s", targColl, collEnt.collName + collLen); #else if ((status = splitPathByKey ( collEnt.collName, parPath, childPath, '/')) < 0) { rodsLogError (LOG_ERROR, status, "rsyncCollToCollUtil:: splitPathByKey for %s error, status = %d", collEnt.collName, status); return (status); } snprintf (targChildPath, MAX_NAME_LEN, "%s/%s", targColl, childPath); #endif if ( rodsArgs->longOption != True ) { /* only do the sync if no -l option specified */ #ifdef FILESYSTEM_META mkCollWithSrcCollMeta (conn, targChildPath, collEnt.collName); #else mkColl (conn, targChildPath); #endif } #if 0 if (collEnt.specColl.collClass != NO_SPEC_COLL) { #endif /* the child is a spec coll. need to drill down */ childDataObjCopyInp = *dataObjCopyInp; if (collEnt.specColl.collClass != NO_SPEC_COLL) childDataObjCopyInp.srcDataObjInp.specColl = &collEnt.specColl; rstrcpy (myTargPath.outPath, targChildPath, MAX_NAME_LEN); rstrcpy (mySrcPath.outPath, collEnt.collName, MAX_NAME_LEN); status = rsyncCollToCollUtil (conn, &mySrcPath, &myTargPath, myRodsEnv, rodsArgs, &childDataObjCopyInp); if (status < 0 && status != CAT_NO_ROWS_FOUND) { return (status); } #if 0 } #endif } } rclCloseCollection (&collHandle); if (savedStatus < 0) { return (savedStatus); } else if (status == CAT_NO_ROWS_FOUND || status == SYS_SPEC_COLL_OBJ_NOT_EXIST) { return (0); } else { return (status); } } int initCondForRsync (rodsEnv *myRodsEnv, rodsArguments_t *rodsArgs, dataObjInp_t *dataObjInp) { char *myResc = NULL; char tmpStr[NAME_LEN]; if (dataObjInp == NULL) { rodsLog (LOG_ERROR, "initCondForRsync: NULL dataObjOprInp input"); return (USER__NULL_INPUT_ERR); } memset (dataObjInp, 0, sizeof (dataObjInp_t)); if (rodsArgs == NULL) { return (0); } /* always turn on the force flag */ addKeyVal (&dataObjInp->condInput, FORCE_FLAG_KW, ""); if (rodsArgs->sizeFlag == True) { addKeyVal (&dataObjInp->condInput, VERIFY_BY_SIZE_KW, ""); } if (rodsArgs->all == True) { addKeyVal (&dataObjInp->condInput, ALL_KW, ""); } #ifdef windows_platform dataObjInp->numThreads = NO_THREADING; #else if (rodsArgs->number == True) { if (rodsArgs->numberValue == 0) { dataObjInp->numThreads = NO_THREADING; } else { dataObjInp->numThreads = rodsArgs->numberValue; } } #endif if (rodsArgs->resource == True) { if (rodsArgs->resourceString == NULL) { rodsLog (LOG_ERROR, "initCondForRepl: NULL resourceString error"); return (USER__NULL_INPUT_ERR); } else { myResc = rodsArgs->resourceString; addKeyVal (&dataObjInp->condInput, DEST_RESC_NAME_KW, rodsArgs->resourceString); } } else if (myRodsEnv != NULL && strlen (myRodsEnv->rodsDefResource) > 0) { myResc = myRodsEnv->rodsDefResource; addKeyVal (&dataObjInp->condInput, DEST_RESC_NAME_KW, myRodsEnv->rodsDefResource); } if (rodsArgs->age == True) { snprintf (tmpStr, NAME_LEN, "%d", rodsArgs->agevalue); addKeyVal (&dataObjInp->condInput, AGE_KW, tmpStr); } return (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 ); }
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; 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); }
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); }
/** * \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); }
int mountFileDir (rsComm_t *rsComm, dataObjInp_t *phyPathRegInp, char *filePath, rescInfo_t *rescInfo) { collInp_t collCreateInp; int rescTypeInx; int status; fileStatInp_t fileStatInp; rodsStat_t *myStat = NULL; rodsObjStat_t *rodsObjStatOut = NULL; if (rsComm->clientUser.authInfo.authFlag < LOCAL_PRIV_USER_AUTH) return(CAT_INSUFFICIENT_PRIVILEGE_LEVEL); status = collStat (rsComm, phyPathRegInp, &rodsObjStatOut); if (status < 0) return status; if (rodsObjStatOut->specColl != NULL) { freeRodsObjStat (rodsObjStatOut); rodsLog (LOG_ERROR, "mountFileDir: %s already mounted", phyPathRegInp->objPath); return (SYS_MOUNT_MOUNTED_COLL_ERR); } freeRodsObjStat (rodsObjStatOut); if (isCollEmpty (rsComm, phyPathRegInp->objPath) == False) { rodsLog (LOG_ERROR, "mountFileDir: collection %s not empty", phyPathRegInp->objPath); return (SYS_COLLECTION_NOT_EMPTY); } memset (&fileStatInp, 0, sizeof (fileStatInp)); rstrcpy (fileStatInp.fileName, filePath, MAX_NAME_LEN); rescTypeInx = rescInfo->rescTypeInx; fileStatInp.fileType = (fileDriverType_t)RescTypeDef[rescTypeInx].driverType; rstrcpy (fileStatInp.addr.hostAddr, rescInfo->rescLoc, NAME_LEN); status = rsFileStat (rsComm, &fileStatInp, &myStat); if (status < 0) { fileMkdirInp_t fileMkdirInp; rodsLog (LOG_NOTICE, "mountFileDir: rsFileStat failed for %s, status = %d, create it", fileStatInp.fileName, status); memset (&fileMkdirInp, 0, sizeof (fileMkdirInp)); rstrcpy (fileMkdirInp.dirName, filePath, MAX_NAME_LEN); fileMkdirInp.fileType = (fileDriverType_t)RescTypeDef[rescTypeInx].driverType; fileMkdirInp.mode = getDefDirMode (); rstrcpy (fileMkdirInp.addr.hostAddr, rescInfo->rescLoc, NAME_LEN); status = rsFileMkdir (rsComm, &fileMkdirInp); if (status < 0) { return (status); } } else if ((myStat->st_mode & S_IFDIR) == 0) { rodsLog (LOG_ERROR, "mountFileDir: phyPath %s is not a directory", fileStatInp.fileName); free (myStat); return (USER_FILE_DOES_NOT_EXIST); } free (myStat); /* mk the collection */ memset (&collCreateInp, 0, sizeof (collCreateInp)); rstrcpy (collCreateInp.collName, phyPathRegInp->objPath, MAX_NAME_LEN); addKeyVal (&collCreateInp.condInput, COLLECTION_TYPE_KW, MOUNT_POINT_STR); addKeyVal (&collCreateInp.condInput, COLLECTION_INFO1_KW, filePath); addKeyVal (&collCreateInp.condInput, COLLECTION_INFO2_KW, rescInfo->rescName); /* try to mod the coll first */ status = rsModColl (rsComm, &collCreateInp); if (status < 0) { /* try to create it */ status = rsRegColl (rsComm, &collCreateInp); } if (status >= 0) { char outLogPath[MAX_NAME_LEN]; int status1; /* see if the phyPath is mapped into a real collection */ if (getLogPathFromPhyPath (filePath, rescInfo, outLogPath) >= 0 && strcmp (outLogPath, phyPathRegInp->objPath) != 0) { /* log path not the same as input objPath */ if (isColl (rsComm, outLogPath, NULL) >= 0) { modAccessControlInp_t modAccessControl; /* it is a real collection. better set the collection * to read-only mode because any modification to files * through this mounted collection can be trouble */ bzero (&modAccessControl, sizeof (modAccessControl)); modAccessControl.accessLevel = "read"; modAccessControl.userName = rsComm->clientUser.userName; modAccessControl.zone = rsComm->clientUser.rodsZone; modAccessControl.path = phyPathRegInp->objPath; status1 = rsModAccessControl(rsComm, &modAccessControl); if (status1 < 0) { rodsLog (LOG_NOTICE, "mountFileDir: rsModAccessControl err for %s, stat = %d", phyPathRegInp->objPath, status1); } } } } return (status); }
int _irodsGetattr (iFuseConn_t *iFuseConn, const char *path, struct stat *stbuf) { int status; dataObjInp_t dataObjInp; rodsObjStat_t *rodsObjStatOut = NULL; #ifdef CACHE_FUSE_PATH pathCache_t *tmpPathCache; #endif rodsLog (LOG_DEBUG, "_irodsGetattr: %s", path); #ifdef CACHE_FUSE_PATH /*if (lookupPathNotExist( (char *) path) == 1) { rodsLog (LOG_DEBUG, "irodsGetattr: a match for non existing path %s", path); return -ENOENT; }*/ if (matchAndLockPathCache ((char *) path, &tmpPathCache) == 1) { rodsLog (LOG_DEBUG, "irodsGetattr: a match for path %s", path); if (tmpPathCache->fileCache != NULL) { LOCK_STRUCT(*(tmpPathCache->fileCache)); if(tmpPathCache->fileCache->state == HAVE_NEWLY_CREATED_CACHE) { status = _updatePathCacheStatFromFileCache (tmpPathCache); UNLOCK_STRUCT(*(tmpPathCache->fileCache)); UNLOCK_STRUCT(*tmpPathCache); if (status < 0) { clearPathFromCache ((char *) path); } else { *stbuf = tmpPathCache->stbuf; return (0); } } else { UNLOCK_STRUCT(*(tmpPathCache->fileCache)); UNLOCK_STRUCT(*tmpPathCache); } } else { UNLOCK_STRUCT(*tmpPathCache); } } #endif memset (stbuf, 0, sizeof (struct stat)); memset (&dataObjInp, 0, sizeof (dataObjInp)); status = parseRodsPathStr ((char *) (path + 1) , &MyRodsEnv, dataObjInp.objPath); if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsGetattr: parseRodsPathStr of %s error", path); /* use ENOTDIR for this type of error */ return -ENOTDIR; } status = rcObjStat (iFuseConn->conn, &dataObjInp, &rodsObjStatOut); if (status < 0) { if (isReadMsgError (status)) { ifuseReconnect (iFuseConn); status = rcObjStat (iFuseConn->conn, &dataObjInp, &rodsObjStatOut); } if (status < 0) { if (status != USER_FILE_DOES_NOT_EXIST) { rodsLogError (LOG_ERROR, status, "irodsGetattr: rcObjStat of %s error", path); } #ifdef CACHE_FUSE_PATH pathNotExist ((char *) path); #endif return -ENOENT; } } if (rodsObjStatOut->objType == COLL_OBJ_T) { fillDirStat (stbuf, atoi (rodsObjStatOut->createTime), atoi (rodsObjStatOut->modifyTime), atoi (rodsObjStatOut->modifyTime)); } else if (rodsObjStatOut->objType == UNKNOWN_OBJ_T) { pathNotExist ((char *) path); if (rodsObjStatOut != NULL) freeRodsObjStat (rodsObjStatOut); return -ENOENT; } else { fillFileStat (stbuf, rodsObjStatOut->dataMode, rodsObjStatOut->objSize, atoi (rodsObjStatOut->createTime), atoi (rodsObjStatOut->modifyTime), atoi (rodsObjStatOut->modifyTime)); } if (rodsObjStatOut != NULL) freeRodsObjStat (rodsObjStatOut); /* don't set file cache */ pathExist ((char *) path, NULL, stbuf, &tmpPathCache); return 0; }
/// =-=-=-=-=-=-=- /// @brief function to query resource for chosen server to which to redirect /// for a given operation error resolve_resource_hierarchy( const std::string& _oper, rsComm_t* _comm, dataObjInp_t* _data_obj_inp, std::string& _out_hier ) { // =-=-=-=-=-=-=- // validate incoming parameters if ( !_comm ) { return ERROR( SYS_INVALID_INPUT_PARAM, "null comm pointer" ); } else if ( !_data_obj_inp ) { return ERROR( SYS_INVALID_INPUT_PARAM, "null data obj inp pointer" ); } // =-=-=-=-=-=-=- // cache the operation, as we may need to modify it std::string oper = _oper; // =-=-=-=-=-=-=- // if this is a put operation then we do not have a first class object resource_ptr resc; file_object_ptr file_obj( new file_object( ) ); // =-=-=-=-=-=-=- // if this is a special collection then we need to get the hier // pass that along and bail as it is not a data object, or if // it is just a not-so-special collection then we continue with // processing the operation, as this may be a create op rodsObjStat_t *rodsObjStatOut = NULL; int spec_stat = collStat( _comm, _data_obj_inp, &rodsObjStatOut ); file_obj->logical_path( _data_obj_inp->objPath ); if ( spec_stat >= 0 ) { if ( rodsObjStatOut->specColl != NULL ) { _out_hier = rodsObjStatOut->specColl->rescHier; freeRodsObjStat( rodsObjStatOut ); return SUCCESS(); } } freeRodsObjStat( rodsObjStatOut ); // =-=-=-=-=-=-=- // extract the resc name keyword from the conditional input char* back_up_resc_name = getValByKey( &_data_obj_inp->condInput, BACKUP_RESC_NAME_KW ); char* dest_resc_name = getValByKey( &_data_obj_inp->condInput, DEST_RESC_NAME_KW ); char* default_resc_name = getValByKey( &_data_obj_inp->condInput, DEF_RESC_NAME_KW ); char* resc_name = getValByKey( &_data_obj_inp->condInput, RESC_NAME_KW ); // =-=-=-=-=-=-=- // assign the keyword in an order, if it applies char* key_word = 0; if ( resc_name ) { key_word = resc_name; } else if ( dest_resc_name ) { key_word = dest_resc_name; } else if ( back_up_resc_name ) { key_word = back_up_resc_name; } // =-=-=-=-=-=-=- // call factory for given obj inp, get a file_object error fac_err = file_object_factory( _comm, _data_obj_inp, file_obj ); // =-=-=-=-=-=-=- // perform an open operation if create is not specificied ( thats all we have for now ) if ( OPEN_OPERATION == oper || WRITE_OPERATION == oper ) { // =-=-=-=-=-=-=- // factory has already been called, test for // success before proceeding if ( !fac_err.ok() ) { std::stringstream msg; msg << "resolve_resource_hierarchy :: failed in file_object_factory"; return PASSMSG( msg.str(), fac_err ); } // =-=-=-=-=-=-=- // consider force flag - we need to consider the default // resc if -f is specified char* force_flag = getValByKey( &_data_obj_inp->condInput, FORCE_FLAG_KW ); if ( force_flag && !key_word ) { key_word = default_resc_name; } // =-=-=-=-=-=-=- // attempt to resolve for an open _out_hier = ""; error ret = resolve_hier_for_open_or_write( _comm, file_obj, key_word, oper, _out_hier ); return ret; } else if ( CREATE_OPERATION == oper ) { // =-=-=-=-=-=-=- // include the default resc name if it applies if ( !key_word && default_resc_name ) { key_word = default_resc_name; } // =-=-=-=-=-=-=- // if we have valid data objects then this could // be actually an open rather than a pure create error ret = SUCCESS(); if ( fac_err.ok() ) { ret = resolve_hier_for_create_or_open( _comm, file_obj, key_word, _data_obj_inp, _out_hier ); } else { // =-=-=-=-=-=-=- // attempt to resolve for a create ret = resolve_hier_for_create( _comm, file_obj, key_word, _data_obj_inp, _out_hier ); } return ret; } // else // =-=-=-=-=-=-=- // should not get here std::stringstream msg; msg << "operation not supported [" << oper << "]"; return ERROR( -1, msg.str() ); } // resolve_resource_hierarchy
int linkCollReg (rsComm_t *rsComm, dataObjInp_t *phyPathRegInp) { collInp_t collCreateInp; int status; char *linkPath = NULL; char *collType; int len; rodsObjStat_t *rodsObjStatOut = NULL; specCollCache_t *specCollCache = NULL; if ((linkPath = getValByKey (&phyPathRegInp->condInput, FILE_PATH_KW)) == NULL) { rodsLog (LOG_ERROR, "linkCollReg: No linkPath input for %s", phyPathRegInp->objPath); return (SYS_INVALID_FILE_PATH); } collType = getValByKey (&phyPathRegInp->condInput, COLLECTION_TYPE_KW); if (collType == NULL || strcmp (collType, LINK_POINT_STR) != 0) { rodsLog (LOG_ERROR, "linkCollReg: Bad COLLECTION_TYPE_KW for linkPath %s", phyPathRegInp->objPath); return (SYS_INTERNAL_NULL_INPUT_ERR); } if (phyPathRegInp->objPath[0] != '/' || linkPath[0] != '/') { rodsLog (LOG_ERROR, "linkCollReg: linkPath %s or collection %s not absolute path", linkPath, phyPathRegInp->objPath); return (SYS_COLL_LINK_PATH_ERR); } len = strlen (phyPathRegInp->objPath); if (strncmp (linkPath, phyPathRegInp->objPath, len) == 0 && linkPath[len] == '/') { rodsLog (LOG_ERROR, "linkCollReg: linkPath %s inside collection %s", linkPath, phyPathRegInp->objPath); return (SYS_COLL_LINK_PATH_ERR); } len = strlen (linkPath); if (strncmp (phyPathRegInp->objPath, linkPath, len) == 0 && phyPathRegInp->objPath[len] == '/') { rodsLog (LOG_ERROR, "linkCollReg: collection %s inside linkPath %s", linkPath, phyPathRegInp->objPath); return (SYS_COLL_LINK_PATH_ERR); } if (getSpecCollCache (rsComm, linkPath, 0, &specCollCache) >= 0 && specCollCache->specColl.collClass != LINKED_COLL) { rodsLog (LOG_ERROR, "linkCollReg: linkPath %s is in a spec coll path", linkPath); return (SYS_COLL_LINK_PATH_ERR); } status = collStat (rsComm, phyPathRegInp, &rodsObjStatOut); if (status < 0) { /* does not exist. make one */ collInp_t collCreateInp; memset (&collCreateInp, 0, sizeof (collCreateInp)); rstrcpy (collCreateInp.collName, phyPathRegInp->objPath, MAX_NAME_LEN); status = rsRegColl (rsComm, &collCreateInp); if (status < 0) { rodsLog (LOG_ERROR, "linkCollReg: rsRegColl error for %s, status = %d", collCreateInp.collName, status); return status; } status = collStat (rsComm, phyPathRegInp, &rodsObjStatOut); if (status < 0) return status; } if (rodsObjStatOut->specColl != NULL && rodsObjStatOut->specColl->collClass != LINKED_COLL) { freeRodsObjStat (rodsObjStatOut); rodsLog (LOG_ERROR, "linkCollReg: link collection %s in a spec coll path", phyPathRegInp->objPath); return (SYS_COLL_LINK_PATH_ERR); } freeRodsObjStat (rodsObjStatOut); if (isCollEmpty (rsComm, phyPathRegInp->objPath) == False) { rodsLog (LOG_ERROR, "linkCollReg: collection %s not empty", phyPathRegInp->objPath); return (SYS_COLLECTION_NOT_EMPTY); } /* mk the collection */ memset (&collCreateInp, 0, sizeof (collCreateInp)); rstrcpy (collCreateInp.collName, phyPathRegInp->objPath, MAX_NAME_LEN); addKeyVal (&collCreateInp.condInput, COLLECTION_TYPE_KW, collType); /* have to use dataObjInp.objPath because structFile path was removed */ addKeyVal (&collCreateInp.condInput, COLLECTION_INFO1_KW, linkPath); /* try to mod the coll first */ status = rsModColl (rsComm, &collCreateInp); if (status < 0) { /* try to create it */ status = rsRegColl (rsComm, &collCreateInp); } return (status); }
int chkCollForExtAndReg (rsComm_t *rsComm, char *collection, rodsObjStat_t **rodsObjStatOut) { dataObjInp_t dataObjInp; int status; rodsObjStat_t *myRodsObjStat = NULL; bzero (&dataObjInp, sizeof (dataObjInp)); rstrcpy (dataObjInp.objPath, collection, MAX_NAME_LEN); #if 0 /* allow mounted coll */ status = collStat (rsComm, &dataObjInp, &myRodsObjStat); #endif status = collStatAllKinds (rsComm, &dataObjInp, &myRodsObjStat); #if 0 if (status == CAT_NO_ROWS_FOUND || status == OBJ_PATH_DOES_NOT_EXIST || status == USER_FILE_DOES_NOT_EXIST) { #endif if (status < 0) { status = rsMkCollR (rsComm, "/", collection); if (status < 0) { rodsLog (LOG_ERROR, "chkCollForExtAndReg: rsMkCollR of %s error. status = %d", collection, status); return (status); } else { #if 0 /* allow mounted coll */ status = collStat (rsComm, &dataObjInp, &myRodsObjStat); #endif status = collStatAllKinds (rsComm, &dataObjInp, &myRodsObjStat); } } if (status < 0) { rodsLog (LOG_ERROR, "chkCollForExtAndReg: collStat of %s error. status = %d", dataObjInp.objPath, status); return (status); } else if (myRodsObjStat->specColl != NULL && myRodsObjStat->specColl->collClass != MOUNTED_COLL) { /* only do mounted coll */ freeRodsObjStat (myRodsObjStat); rodsLog (LOG_ERROR, "chkCollForExtAndReg: %s is a struct file collection", dataObjInp.objPath); return (SYS_STRUCT_FILE_INMOUNTED_COLL); } if (myRodsObjStat->specColl == NULL) { status = checkCollAccessPerm (rsComm, collection, ACCESS_DELETE_OBJECT); } else { status = checkCollAccessPerm (rsComm, myRodsObjStat->specColl->collection, ACCESS_DELETE_OBJECT); } if (status < 0) { rodsLog (LOG_ERROR, "chkCollForExtAndReg: no permission to write %s, status = %d", collection, status); freeRodsObjStat (myRodsObjStat); } else { if (rodsObjStatOut != NULL) { *rodsObjStatOut = myRodsObjStat; } else { freeRodsObjStat (myRodsObjStat); } } return (status); } /* regUnbunSubfiles - non bulk version of registering all files in phyBunDir * to the collection. Valid values for flags are: * FORCE_FLAG_FLAG. */ int regUnbunSubfiles (rsComm_t *rsComm, rescInfo_t *rescInfo, char *rescGroupName, char *collection, char *phyBunDir, int flags, genQueryOut_t *attriArray) { #ifndef USE_BOOST_FS DIR *dirPtr; struct dirent *myDirent; struct stat statbuf; #endif char subfilePath[MAX_NAME_LEN]; char subObjPath[MAX_NAME_LEN]; dataObjInp_t dataObjInp; int status; int savedStatus = 0; rodsLong_t st_size; #ifdef USE_BOOST_FS path srcDirPath (phyBunDir); if (!exists(srcDirPath) || !is_directory(srcDirPath)) { #else dirPtr = opendir (phyBunDir); if (dirPtr == NULL) { #endif rodsLog (LOG_ERROR, "regUnbunphySubfiles: opendir error for %s, errno = %d", phyBunDir, errno); return (UNIX_FILE_OPENDIR_ERR - errno); } bzero (&dataObjInp, sizeof (dataObjInp)); #ifdef USE_BOOST_FS directory_iterator end_itr; // default construction yields past-the-end for (directory_iterator itr(srcDirPath); itr != end_itr;++itr) { path p = itr->path(); snprintf (subfilePath, MAX_NAME_LEN, "%s", p.c_str ()); #else while ((myDirent = readdir (dirPtr)) != NULL) { if (strcmp (myDirent->d_name, ".") == 0 || strcmp (myDirent->d_name, "..") == 0) { continue; } snprintf (subfilePath, MAX_NAME_LEN, "%s/%s", phyBunDir, myDirent->d_name); #endif #ifdef USE_BOOST_FS if (!exists (p)) { #else status = lstat (subfilePath, &statbuf); if (status != 0) { #endif rodsLog (LOG_ERROR, "regUnbunphySubfiles: stat error for %s, errno = %d", subfilePath, errno); savedStatus = UNIX_FILE_STAT_ERR - errno; unlink (subfilePath); continue; } #ifdef USE_BOOST_FS if (is_symlink (p)) { #else if ((statbuf.st_mode & S_IFLNK) == S_IFLNK) { #endif rodsLogError (LOG_ERROR, SYMLINKED_BUNFILE_NOT_ALLOWED, "regUnbunSubfiles: %s is a symlink", subfilePath); savedStatus = SYMLINKED_BUNFILE_NOT_ALLOWED; continue; } #ifdef USE_BOOST_FS path childPath = p.filename(); snprintf (subObjPath, MAX_NAME_LEN, "%s/%s", collection, childPath.c_str()); if (is_directory (p)) { #else snprintf (subObjPath, MAX_NAME_LEN, "%s/%s", collection, myDirent->d_name); if ((statbuf.st_mode & S_IFDIR) != 0) { #endif status = rsMkCollR (rsComm, "/", subObjPath); if (status < 0) { rodsLog (LOG_ERROR, "regUnbunSubfiles: rsMkCollR of %s error. status = %d", subObjPath, status); savedStatus = status; continue; } status = regUnbunSubfiles (rsComm, rescInfo, rescGroupName, subObjPath, subfilePath, flags, attriArray); if (status < 0) { rodsLog (LOG_ERROR, "regUnbunSubfiles: regUnbunSubfiles of %s error. status=%d", subObjPath, status); savedStatus = status; continue; } #ifdef USE_BOOST_FS } else if (is_regular_file (p)) { st_size = file_size (p); #else } else if ((statbuf.st_mode & S_IFREG) != 0) { st_size = statbuf.st_size; #endif status = regSubfile (rsComm, rescInfo, rescGroupName, subObjPath, subfilePath, st_size, flags); unlink (subfilePath); if (status < 0) { rodsLog (LOG_ERROR, "regUnbunSubfiles: regSubfile of %s error. status=%d", subObjPath, status); savedStatus = status; continue; } } } #ifndef USE_BOOST_FS closedir (dirPtr); #endif rmdir (phyBunDir); return savedStatus; } int regSubfile (rsComm_t *rsComm, rescInfo_t *rescInfo, char *rescGroupName, char *subObjPath, char *subfilePath, rodsLong_t dataSize, int flags) { dataObjInfo_t dataObjInfo; dataObjInp_t dataObjInp; #ifndef USE_BOOST_FS struct stat statbuf; #endif int status; int modFlag = 0; bzero (&dataObjInp, sizeof (dataObjInp)); bzero (&dataObjInfo, sizeof (dataObjInfo)); rstrcpy (dataObjInp.objPath, subObjPath, MAX_NAME_LEN); rstrcpy (dataObjInfo.objPath, subObjPath, MAX_NAME_LEN); rstrcpy (dataObjInfo.rescName, rescInfo->rescName, NAME_LEN); rstrcpy (dataObjInfo.dataType, "generic", NAME_LEN); dataObjInfo.rescInfo = rescInfo; rstrcpy (dataObjInfo.rescGroupName, rescGroupName, NAME_LEN); dataObjInfo.dataSize = dataSize; status = getFilePathName (rsComm, &dataObjInfo, &dataObjInp); if (status < 0) { rodsLog (LOG_ERROR, "regSubFile: getFilePathName err for %s. status = %d", dataObjInp.objPath, status); return (status); } #ifdef USE_BOOST_FS path p (dataObjInfo.filePath); if (exists (p)) { if (is_directory (p)) { #else status = stat (dataObjInfo.filePath, &statbuf); if (status == 0 || errno != ENOENT) { if ((statbuf.st_mode & S_IFDIR) != 0) { #endif return SYS_PATH_IS_NOT_A_FILE; } if (chkOrphanFile (rsComm, dataObjInfo.filePath, rescInfo->rescName, &dataObjInfo) > 0) { /* an orphan file. just rename it */ fileRenameInp_t fileRenameInp; bzero (&fileRenameInp, sizeof (fileRenameInp)); rstrcpy (fileRenameInp.oldFileName, dataObjInfo.filePath, MAX_NAME_LEN); status = renameFilePathToNewDir (rsComm, ORPHAN_DIR, &fileRenameInp, rescInfo, 1); if (status < 0) { rodsLog (LOG_ERROR, "regSubFile: renameFilePathToNewDir err for %s. status = %d", fileRenameInp.oldFileName, status); return (status); } } else { /* not an orphan file */ if ((flags & FORCE_FLAG_FLAG) != 0 && dataObjInfo.dataId > 0 && strcmp (dataObjInfo.objPath, subObjPath) == 0) { /* overwrite the current file */ modFlag = 1; unlink (dataObjInfo.filePath); } else { status = SYS_COPY_ALREADY_IN_RESC; rodsLog (LOG_ERROR, "regSubFile: phypath %s is already in use. status = %d", dataObjInfo.filePath, status); return (status); } } } /* make the necessary dir */ mkDirForFilePath (UNIX_FILE_TYPE, rsComm, "/", dataObjInfo.filePath, getDefDirMode ()); /* add a link */ #ifndef windows_platform /* Windows does not support link */ status = link (subfilePath, dataObjInfo.filePath); if (status < 0) { rodsLog (LOG_ERROR, "regSubFile: link error %s to %s. errno = %d", subfilePath, dataObjInfo.filePath, errno); return (UNIX_FILE_LINK_ERR - errno); } #endif if (modFlag == 0) { status = svrRegDataObj (rsComm, &dataObjInfo); } else { char tmpStr[MAX_NAME_LEN]; modDataObjMeta_t modDataObjMetaInp; keyValPair_t regParam; bzero (&modDataObjMetaInp, sizeof (modDataObjMetaInp)); bzero (®Param, sizeof (regParam)); snprintf (tmpStr, MAX_NAME_LEN, "%lld", dataSize); addKeyVal (®Param, DATA_SIZE_KW, tmpStr); addKeyVal (®Param, ALL_REPL_STATUS_KW, tmpStr); snprintf (tmpStr, MAX_NAME_LEN, "%d", (int) time (NULL)); addKeyVal (®Param, DATA_MODIFY_KW, tmpStr); modDataObjMetaInp.dataObjInfo = &dataObjInfo; modDataObjMetaInp.regParam = ®Param; status = rsModDataObjMeta (rsComm, &modDataObjMetaInp); clearKeyVal (®Param); } if (status < 0) { rodsLog (LOG_ERROR, "regSubFile: svrRegDataObj of %s. errno = %d", dataObjInfo.objPath, errno); unlink (dataObjInfo.filePath); } else { ruleExecInfo_t rei; dataObjInp_t dataObjInp; bzero (&dataObjInp, sizeof (dataObjInp)); rstrcpy (dataObjInp.objPath, dataObjInfo.objPath, MAX_NAME_LEN); initReiWithDataObjInp (&rei, rsComm, &dataObjInp); rei.doi = &dataObjInfo; rei.status = applyRule ("acPostProcForTarFileReg", NULL, &rei, NO_SAVE_REI); if (rei.status < 0) { rodsLogError (LOG_ERROR, rei.status, "regSubFile: acPostProcForTarFileReg error for %s. status = %d", dataObjInfo.objPath); } } return status; }