Exemple #1
0
int
resolveLinkedPath( rsComm_t *rsComm, char *objPath,
                   specCollCache_t **specCollCache, keyValPair_t *condInput ) {
    int linkCnt = 0;
    specColl_t *curSpecColl;
    char prevNewPath[MAX_NAME_LEN];
    specCollCache_t *oldSpecCollCache = NULL;
    int status;

    *specCollCache = NULL;

    if ( getValByKey( condInput, TRANSLATED_PATH_KW ) != NULL ) {
        return 0;
    }

    addKeyVal( condInput, TRANSLATED_PATH_KW, "" );
    while ( getSpecCollCache( rsComm, objPath, 0,  specCollCache ) >= 0 &&
            ( *specCollCache )->specColl.collClass == LINKED_COLL ) {
        oldSpecCollCache = *specCollCache;
        if ( linkCnt++ >= MAX_LINK_CNT ) {
            rodsLog( LOG_ERROR,
                     "resolveLinkedPath: linkCnt for %s exceeds %d",
                     objPath, MAX_LINK_CNT );
            return SYS_LINK_CNT_EXCEEDED_ERR;
        }

        curSpecColl = &( *specCollCache )->specColl;
        if ( strcmp( curSpecColl->collection, objPath ) == 0 &&
                getValByKey( condInput, NO_TRANSLATE_LINKPT_KW ) != NULL ) {
            return 0;
        }
        rstrcpy( prevNewPath, objPath, MAX_NAME_LEN );
        status = getMountedSubPhyPath( curSpecColl->collection,
                                       curSpecColl->phyPath, prevNewPath, objPath );
        if ( status < 0 ) {
            return status;
        }
    }
    if ( *specCollCache == NULL ) {
        *specCollCache = oldSpecCollCache;
    }
    return linkCnt;
}
Exemple #2
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);
}
int
rsGetHostForGet (rsComm_t *rsComm, dataObjInp_t *dataObjInp,
char **outHost)
{
    int status;
    rescInfo_t *myRescInfo;
    char *myResc;
    rodsServerHost_t *rodsServerHost;
    rodsHostAddr_t addr;
    specCollCache_t *specCollCache = NULL;
    char *myHost;
    int remoteFlag;

    *outHost = NULL;

#if 0
    if (isLocalZone (dataObjInp->objPath) == 0) {
	/* it is a remote zone. better connect to this host */
	*outHost = strdup (THIS_ADDRESS);
	return 0;
    }
#endif

    resolveLinkedPath (rsComm, dataObjInp->objPath, &specCollCache, NULL);
    if (isLocalZone (dataObjInp->objPath) == 0) {
#if 0
        /* it is a remote zone. better connect to this host */
        *outHost = strdup (THIS_ADDRESS);
        return 0;
#else
        resolveLinkedPath (rsComm, dataObjInp->objPath, &specCollCache,
          &dataObjInp->condInput);
        remoteFlag = getAndConnRcatHost (rsComm, SLAVE_RCAT, 
	  dataObjInp->objPath, &rodsServerHost);
        if (remoteFlag < 0) {
            return (remoteFlag);
        } else if (remoteFlag == LOCAL_HOST) {
	    *outHost = strdup (THIS_ADDRESS);
            return 0;
	} else {
            status = rcGetHostForGet (rodsServerHost->conn, dataObjInp, 
	      outHost);
	    if (status >= 0 && *outHost != NULL && 
	      strcmp (*outHost, THIS_ADDRESS) == 0) {
		free (*outHost);
		*outHost = strdup (rodsServerHost->hostName->name);
	    }
            return (status);
	}
#endif
    }
    status = getSpecCollCache (rsComm, dataObjInp->objPath, 0, &specCollCache);
    if (status >= 0) {
	if (specCollCache->specColl.collClass == MOUNTED_COLL) {
            status = resolveResc (specCollCache->specColl.resource, 
	      &myRescInfo);
            if (status < 0) {
                rodsLog (LOG_ERROR,
                  "rsGetHostForGet: resolveResc error for %s, status = %d",
                 specCollCache->specColl.resource, status);
		return status;
            }
	    /* mounted coll will fall through with myRescInfo */
        } else {
            *outHost = strdup (THIS_ADDRESS);
            return 0;
	}
    } else if ((myResc = getValByKey (&dataObjInp->condInput, RESC_NAME_KW)) 
      != NULL && resolveResc (myResc, &myRescInfo) >= 0) {
	/* user specified a resource. myRescInfo set and fall through */
    } else {
	/* normal type */
        status = getBestRescForGet (rsComm, dataObjInp, &myRescInfo);
	if (myRescInfo == NULL) {
	    *outHost = strdup (THIS_ADDRESS);
            return status;
	}
    }

    /* get down here when we got a valid myRescInfo */

    if (getRescClass (myRescInfo) == COMPOUND_CL) {
        *outHost = strdup (THIS_ADDRESS);
        return 0;
    }

    bzero (&addr, sizeof (addr));
    rstrcpy (addr.hostAddr, myRescInfo->rescLoc, NAME_LEN);
    status = resolveHost (&addr, &rodsServerHost);
    if (status < 0) return status;
    if (rodsServerHost->localFlag == LOCAL_HOST) {
        *outHost = strdup (THIS_ADDRESS);
        return 0;
    }

    myHost = getSvrAddr (rodsServerHost);
    if (myHost != NULL) {
	*outHost = strdup (myHost);
        return 0;
    } else {
        *outHost = NULL;
	return SYS_INVALID_SERVER_HOST;
    }
}
Exemple #4
0
/* resolvePathInSpecColl - given the object path in dataObjInp->objPath, see if
 * it is in the path of a special collection (mounted or structfile).
 * If it is not in a special collection, returns a -ive value.
 * The inCachOnly flag asks it to check the specColl in the global cache only
 * If it is, returns a dataObjInfo struct with dataObjInfo->specColl != NULL.
 * Returns COLL_OBJ_T if the path is a collection or DATA_OBJ_T if the
 * path is a data oobject.
 */
int
resolvePathInSpecColl( rsComm_t *rsComm, char *objPath,
                       specCollPerm_t specCollPerm, int inCachOnly, dataObjInfo_t **dataObjInfo ) {
    specCollCache_t *specCollCache;
    specColl_t *cachedSpecColl;
    int status;
    char *accessStr;

    if ( objPath == NULL ) {
        return SYS_INTERNAL_NULL_INPUT_ERR;
    }
    if ( ( status = getSpecCollCache( rsComm, objPath, inCachOnly,
                                      &specCollCache ) ) < 0 ) {

        return status;
    }
    else {
        cachedSpecColl = &specCollCache->specColl;
    }

    if ( specCollPerm != UNKNOWN_COLL_PERM ) {
        if ( specCollPerm == WRITE_COLL_PERM ) {
            accessStr = ACCESS_DELETE_OBJECT;
        }
        else {
            accessStr = ACCESS_READ_OBJECT;
        }

        if ( specCollCache->perm < specCollPerm ) {
            status = checkCollAccessPerm( rsComm, cachedSpecColl->collection,
                                          accessStr );
            if ( status < 0 ) {
                rodsLog( LOG_ERROR,
                         "resolvePathInSpecColl:checkCollAccessPerm err for %s,stat=%d",
                         cachedSpecColl->collection, status );
                return status;
            }
            else {
                specCollCache->perm = specCollPerm;
            }
        }
    }

    status = specCollSubStat( rsComm, cachedSpecColl, objPath,
                              specCollPerm, dataObjInfo );

    if ( status < 0 ) {
        if ( *dataObjInfo != NULL ) {
            /* does not exist. return the dataObjInfo anyway */
            return SYS_SPEC_COLL_OBJ_NOT_EXIST;
        }
        rodsLog( LOG_ERROR,
                 "resolvePathInSpecColl: specCollSubStat error for %s, status = %d",
                 objPath, status );
        return status;
    }
    else {
        if ( *dataObjInfo != NULL ) {
            if ( specCollPerm == WRITE_COLL_PERM ) {
                ( *dataObjInfo )->writeFlag = 1;
            }
        }
    }

    return status;
}
Exemple #5
0
int
statPathInSpecColl( rsComm_t *rsComm, char *objPath,
                    int inCachOnly, rodsObjStat_t **rodsObjStatOut ) {
    int status;
    dataObjInfo_t *dataObjInfo = NULL;
    specColl_t *specColl;
    specCollCache_t *specCollCache;

    if ( ( status = getSpecCollCache( rsComm, objPath, inCachOnly,
                                      &specCollCache ) ) < 0 ) {
        if ( status != SYS_SPEC_COLL_NOT_IN_CACHE &&
                status != CAT_NO_ROWS_FOUND ) {
            rodsLog( LOG_ERROR,
                     "statPathInSpecColl: getSpecCollCache for %s, status = %d",
                     objPath, status );
        }
        return status;
    }

    if ( *rodsObjStatOut == NULL ) {
        *rodsObjStatOut = ( rodsObjStat_t * ) malloc( sizeof( rodsObjStat_t ) );
    }
    memset( *rodsObjStatOut, 0, sizeof( rodsObjStat_t ) );
    specColl = &specCollCache->specColl;
    rstrcpy( ( *rodsObjStatOut )->dataId, specCollCache->collId, NAME_LEN );
    rstrcpy( ( *rodsObjStatOut )->ownerName, specCollCache->ownerName, NAME_LEN );
    rstrcpy( ( *rodsObjStatOut )->ownerZone, specCollCache->ownerZone, NAME_LEN );

    status = specCollSubStat( rsComm, specColl, objPath, UNKNOWN_COLL_PERM, &dataObjInfo );

    if ( status < 0 ) {
        if ( dataObjInfo != NULL ) {
            if ( dataObjInfo->specColl != NULL ) {
                ( *rodsObjStatOut )->specColl = dataObjInfo->specColl;
            }
            else {
                replSpecColl( &specCollCache->specColl,
                              &( *rodsObjStatOut )->specColl );
            }
            if ( specColl->collClass == LINKED_COLL ) {
                rstrcpy( ( *rodsObjStatOut )->specColl->objPath,
                         dataObjInfo->objPath, MAX_NAME_LEN );
            }
            else {
                ( *rodsObjStatOut )->specColl->objPath[0] = '\0';
            }
            dataObjInfo->specColl = NULL;
        }
        ( *rodsObjStatOut )->objType = UNKNOWN_OBJ_T;
        rstrcpy( ( *rodsObjStatOut )->createTime, specCollCache->createTime,
                 TIME_LEN );
        rstrcpy( ( *rodsObjStatOut )->modifyTime, specCollCache->modifyTime,
                 TIME_LEN );
        freeAllDataObjInfo( dataObjInfo );
        /* XXXXX 0 return is creating a problem for fuse */
        return 0;
    }
    else {
        ( *rodsObjStatOut )->specColl = dataObjInfo->specColl;
        dataObjInfo->specColl = NULL;

        if ( specColl->collClass == LINKED_COLL ) {
            rstrcpy( ( *rodsObjStatOut )->ownerName, dataObjInfo->dataOwnerName,
                     NAME_LEN );
            rstrcpy( ( *rodsObjStatOut )->ownerZone, dataObjInfo->dataOwnerZone,
                     NAME_LEN );
            snprintf( ( *rodsObjStatOut )->dataId, NAME_LEN, "%lld",
                      dataObjInfo->dataId );
            /* save the linked path here */
            rstrcpy( ( *rodsObjStatOut )->specColl->objPath,
                     dataObjInfo->objPath, MAX_NAME_LEN );
        }
        ( *rodsObjStatOut )->objType = ( objType_t )status;
        ( *rodsObjStatOut )->objSize = dataObjInfo->dataSize;
        rstrcpy( ( *rodsObjStatOut )->createTime, dataObjInfo->dataCreate,
                 TIME_LEN );
        rstrcpy( ( *rodsObjStatOut )->modifyTime, dataObjInfo->dataModify,
                 TIME_LEN );
        freeAllDataObjInfo( dataObjInfo );
    }

    return status;
}
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);
}
int
rsGetHostForPut (rsComm_t *rsComm, dataObjInp_t *dataObjInp,
char **outHost)
{
    int status;
    rescGrpInfo_t *myRescGrpInfo;
    rescInfo_t *myRescInfo;
    rodsServerHost_t *rodsServerHost;
    rodsHostAddr_t addr;
    specCollCache_t *specCollCache = NULL;
    char *myHost;
    int remoteFlag;

    *outHost = NULL;

#if 0
    if (isLocalZone (dataObjInp->objPath) == 0) {
	/* it is a remote zone. better connect to this host */
	*outHost = strdup (THIS_ADDRESS);
	return 0;
    }
#endif

    if (getValByKey (&dataObjInp->condInput, ALL_KW) != NULL ||
      getValByKey (&dataObjInp->condInput, FORCE_FLAG_KW) != NULL) {
	/* going to ALL copies or overwriting files. not sure which is the 
         * best */ 
        *outHost = strdup (THIS_ADDRESS);
        return 0;
    }

    resolveLinkedPath (rsComm, dataObjInp->objPath, &specCollCache, NULL);
    if (isLocalZone (dataObjInp->objPath) == 0) {
#if 0
        /* it is a remote zone. better connect to this host */
        *outHost = strdup (THIS_ADDRESS);
        return 0;
#else
        resolveLinkedPath (rsComm, dataObjInp->objPath, &specCollCache,
          &dataObjInp->condInput);
        remoteFlag = getAndConnRcatHost (rsComm, SLAVE_RCAT,
          dataObjInp->objPath, &rodsServerHost);
        if (remoteFlag < 0) {
            return (remoteFlag);
        } else if (remoteFlag == LOCAL_HOST) {
            *outHost = strdup (THIS_ADDRESS);
            return 0;
        } else {
            status = rcGetHostForPut (rodsServerHost->conn, dataObjInp,
              outHost);
            if (status >= 0 && *outHost != NULL &&
              strcmp (*outHost, THIS_ADDRESS) == 0) {
                free (*outHost);
                *outHost = strdup (rodsServerHost->hostName->name);
            }
            return (status);
        }
#endif
    }

    status = getSpecCollCache (rsComm, dataObjInp->objPath, 0, &specCollCache);
    if (status >= 0) {
	if (specCollCache->specColl.collClass == MOUNTED_COLL) {
            status = resolveResc (specCollCache->specColl.resource, 
	      &myRescInfo);
            if (status < 0) {
                rodsLog (LOG_ERROR,
                  "rsGetHostForPut: resolveResc error for %s, status = %d",
                 specCollCache->specColl.resource, status);
		return status;
            }
	    /* mounted coll will fall through */
        } else {
            *outHost = strdup (THIS_ADDRESS);
            return 0;
	}
    } else {
	/* normal type */
        status = getRescGrpForCreate (rsComm, dataObjInp, &myRescGrpInfo);
        if (status < 0) return status;

        myRescInfo = myRescGrpInfo->rescInfo;
	freeAllRescGrpInfo (myRescGrpInfo);
        /* status == 1 means random sorting scheme */
        if ((status == 1 && getRescCnt (myRescGrpInfo) > 1) || 
          getRescClass (myRescInfo) == COMPOUND_CL) {
            *outHost = strdup (THIS_ADDRESS);
	    return 0;
	}
    }
    /* get down here when we got a valid myRescInfo */
    bzero (&addr, sizeof (addr));
    rstrcpy (addr.hostAddr, myRescInfo->rescLoc, NAME_LEN);
    status = resolveHost (&addr, &rodsServerHost);
    if (status < 0) return status;
    if (rodsServerHost->localFlag == LOCAL_HOST) {
        *outHost = strdup (THIS_ADDRESS);
        return 0;
    }

    myHost = getSvrAddr (rodsServerHost);
    if (myHost != NULL) {
	*outHost = strdup (myHost);
        return 0;
    } else {
        *outHost = NULL;
	return SYS_INVALID_SERVER_HOST;
    }
}