Пример #1
0
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;
}
Пример #2
0
/**
 * @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);
}
Пример #3
0
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);
}
Пример #4
0
int
rsRegColl (rsComm_t *rsComm, collInp_t *regCollInp)
{
    int status;
    rodsServerHost_t *rodsServerHost = NULL;
    dataObjInp_t dataObjInp;
    rodsObjStat_t *rodsObjStatOut = NULL;


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

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

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

    return (status);
}
Пример #5
0
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);
}
Пример #6
0
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);
}
Пример #7
0
void
clearRodsPath( rodsPath_t *rodsPath ) {
    if ( rodsPath == NULL ) {
        return;
    }

    if ( rodsPath->rodsObjStat == NULL ) {
        return;
    }

    freeRodsObjStat( rodsPath->rodsObjStat );

    memset( rodsPath, 0, sizeof( rodsPath_t ) );

    return;
}
Пример #8
0
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;
}
Пример #9
0
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;
} 
Пример #10
0
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;
}
Пример #11
0
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;
}
Пример #12
0
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);
}
Пример #13
0
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);
}
Пример #14
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 );
}
Пример #15
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);
}
Пример #16
0
int
dirPathReg (rsComm_t *rsComm, dataObjInp_t *phyPathRegInp, char *filePath,
rescInfo_t *rescInfo)
{
    collInp_t collCreateInp;
    fileOpendirInp_t fileOpendirInp;
    fileClosedirInp_t fileClosedirInp;
    int rescTypeInx;
    int status;
    int dirFd;
    dataObjInp_t subPhyPathRegInp;
    fileReaddirInp_t fileReaddirInp;
    rodsDirent_t *rodsDirent = NULL;
    rodsObjStat_t *rodsObjStatOut = NULL;
    int forceFlag;
    fileStatInp_t fileStatInp;
    rodsStat_t *myStat = NULL;
    char curcoll[MAX_NAME_LEN];

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

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

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

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

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

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

    fileReaddirInp.fileInx = dirFd;

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

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

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

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

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

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

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

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

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

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

    return (status);
}
Пример #17
0
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);
}
Пример #18
0
/**
 * \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);
}
Пример #19
0
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);
}
Пример #20
0
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;
}
Пример #21
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
Пример #22
0
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 (&regParam, sizeof (regParam));
        snprintf (tmpStr, MAX_NAME_LEN, "%lld", dataSize);
        addKeyVal (&regParam, DATA_SIZE_KW, tmpStr);
        addKeyVal (&regParam, ALL_REPL_STATUS_KW, tmpStr);
        snprintf (tmpStr, MAX_NAME_LEN, "%d", (int) time (NULL));
        addKeyVal (&regParam, DATA_MODIFY_KW, tmpStr);

        modDataObjMetaInp.dataObjInfo = &dataObjInfo;
        modDataObjMetaInp.regParam = &regParam;

        status = rsModDataObjMeta (rsComm, &modDataObjMetaInp);

        clearKeyVal (&regParam);
    }

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