Exemple #1
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);
}
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);
}
Exemple #3
0
int
_rsObjStat (rsComm_t *rsComm, dataObjInp_t *dataObjInp,
rodsObjStat_t **rodsObjStatOut)
{
    int status;
    char *tmpStr;
    specCollCache_t *specCollCache;

    /* do data first to catch data registered in spec Coll */ 
    if ((tmpStr = getValByKey (&dataObjInp->condInput, SEL_OBJ_TYPE_KW)) ==
      NULL || strcmp (tmpStr, "dataObj") == 0) {
        status = dataObjStat (rsComm, dataObjInp, rodsObjStatOut);
        if (status >= 0) return (status);
    }

    if (tmpStr == NULL || strcmp (tmpStr, "collection") == 0) {
        status = collStat (rsComm, dataObjInp, rodsObjStatOut);
	/* specColl may already been obtained from collStat */
        if (status >= 0) {
	    if ((*rodsObjStatOut)->specColl == NULL) {
	        if (getSpecCollCache (rsComm, dataObjInp->objPath, 0,
                  &specCollCache) >= 0) {
		    replSpecColl (&specCollCache->specColl, 
		      &(*rodsObjStatOut)->specColl);
	        }
	    }
	    return (status);
	}
    }

    /*  not normal dataObj or coll. now check specColl */
    /* XXXX need to check a rule if it supports spec collection */
    status = statPathInSpecColl (rsComm, dataObjInp->objPath, 0,
      rodsObjStatOut);
    /* use USER_FILE_DOES_NOT_EXIST instead of OBJ_PATH_DOES_NOT_EXIST
     * because icommand depends on it */
    if (status < 0) status = USER_FILE_DOES_NOT_EXIST;
    return (status);
}
/// =-=-=-=-=-=-=-
/// @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
Exemple #5
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;
}
Exemple #6
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);
}
Exemple #7
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);
}
Exemple #8
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);
}
Exemple #9
0
int
dirPathReg (rsComm_t *rsComm, dataObjInp_t *phyPathRegInp, char *filePath,
rescInfo_t *rescInfo)
{
    collInp_t collCreateInp;
    fileOpendirInp_t fileOpendirInp;
    fileClosedirInp_t fileClosedirInp;
    int rescTypeInx;
    int status;
    int dirFd;
    dataObjInp_t subPhyPathRegInp;
    fileReaddirInp_t fileReaddirInp;
    rodsDirent_t *rodsDirent = NULL;
    rodsObjStat_t *rodsObjStatOut = NULL;
    int forceFlag;
    fileStatInp_t fileStatInp;
    rodsStat_t *myStat = NULL;

    rescTypeInx = rescInfo->rescTypeInx;

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

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

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

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

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

    fileReaddirInp.fileInx = dirFd;

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

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

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

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

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

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

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

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

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

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

    return (status);
}
Exemple #10
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;

    status = collStat (rsComm, phyPathRegInp, &rodsObjStatOut);
    if (status < 0) return status;

    if (rodsObjStatOut->specColl != NULL) {
        free (rodsObjStatOut);
        rodsLog (LOG_ERROR,
          "mountFileDir: %s already mounted", phyPathRegInp->objPath);
        return (SYS_MOUNT_MOUNTED_COLL_ERR);
    }
    free (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 = 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 = RescTypeDef[rescTypeInx].driverType;
	fileMkdirInp.mode = DEFAULT_DIR_MODE;
        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);
    }

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

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

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

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

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

    fileReaddirInp.fileInx = dirFd;

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

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

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

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

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

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

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

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

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

    return (status);
}
Exemple #12
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);
}
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;
}