Beispiel #1
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;
}
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;
}