int l3Mkdir( rsComm_t *rsComm, dataObjInfo_t *dataObjInfo ) { //int rescTypeInx; fileMkdirInp_t fileMkdirInp; int status; // =-=-=-=-=-=-=- // extract the host location from the resource hierarchy std::string location; irods::error ret = irods::get_loc_for_hier_string( dataObjInfo->rescHier, location ); if ( !ret.ok() ) { irods::log( PASSMSG( "l3Mkdir - failed in get_loc_for_hier_string", ret ) ); return -1; } if ( getStructFileType( dataObjInfo->specColl ) >= 0 ) { subFile_t subFile; memset( &subFile, 0, sizeof( subFile ) ); rstrcpy( subFile.subFilePath, dataObjInfo->subPath, MAX_NAME_LEN ); subFile.mode = getDefDirMode(); //rstrcpy (subFile.addr.hostAddr, dataObjInfo->rescInfo->rescLoc, NAME_LEN ); rstrcpy( subFile.addr.hostAddr, location.c_str(), NAME_LEN ); subFile.specColl = dataObjInfo->specColl; status = rsSubStructFileMkdir( rsComm, &subFile ); } else { memset( &fileMkdirInp, 0, sizeof( fileMkdirInp ) ); rstrcpy( fileMkdirInp.dirName, dataObjInfo->filePath, MAX_NAME_LEN ); rstrcpy( fileMkdirInp.rescHier, dataObjInfo->rescHier, MAX_NAME_LEN ); rstrcpy( fileMkdirInp.addr.hostAddr, location.c_str(), NAME_LEN ); fileMkdirInp.mode = getDefDirMode(); status = rsFileMkdir( rsComm, &fileMkdirInp ); } return status; }
/// =-=-=-=-=-=-=- /// @brief interface for POSIX mkdir irods::error univ_mss_file_mkdir( irods::resource_plugin_context& _ctx ) { // =-=-=-=-=-=-=- // check context irods::error err = univ_mss_check_param< irods::collection_object >( _ctx ); if ( !err.ok() ) { std::stringstream msg; msg << __FUNCTION__; msg << " - invalid context"; return PASSMSG( msg.str(), err ); } // =-=-=-=-=-=-=- // get the script property std::string script; err = _ctx.prop_map().get< std::string >( SCRIPT_PROP, script ); if ( !err.ok() ) { return PASSMSG( __FUNCTION__, err ); } // =-=-=-=-=-=-=- // snag a ref to the fco irods::collection_object_ptr fco = boost::dynamic_pointer_cast< irods::collection_object >( _ctx.fco() ); std::string dirname = fco->physical_path(); int status = 0; execCmd_t execCmdInp; char cmdArgv[HUGE_NAME_LEN] = ""; execCmdOut_t *execCmdOut = NULL; bzero( &execCmdInp, sizeof( execCmdInp ) ); rstrcpy( execCmdInp.cmd, script.c_str(), LONG_NAME_LEN ); strcat( cmdArgv, "mkdir" ); strcat( cmdArgv, " '" ); strcat( cmdArgv, dirname.c_str() ); strcat( cmdArgv, "'" ); rstrcpy( execCmdInp.cmdArgv, cmdArgv, HUGE_NAME_LEN ); rstrcpy( execCmdInp.execAddr, "localhost", LONG_NAME_LEN ); status = _rsExecCmd( _ctx.comm(), &execCmdInp, &execCmdOut ); if ( status < 0 ) { status = UNIV_MSS_MKDIR_ERR - errno; std::stringstream msg; msg << "univ_mss_file_mkdir - mkdir failed for ["; msg << dirname; msg << "]"; return ERROR( status, msg.str() ); } int mode = getDefDirMode(); fco->mode( mode ); err = univ_mss_file_chmod( _ctx ); return err; } // univ_mss_file_mkdir
/// =-=-=-=-=-=-=- /// @brief interface for POSIX chmod irods::error univ_mss_file_chmod( irods::resource_plugin_context& _ctx ) { // =-=-=-=-=-=-=- // check context irods::error err = univ_mss_check_param< irods::data_object >( _ctx ); if ( !err.ok() ) { std::stringstream msg; msg << __FUNCTION__; msg << " - invalid context"; return PASSMSG( msg.str(), err ); } // =-=-=-=-=-=-=- // get the script property std::string script; err = _ctx.prop_map().get< std::string >( SCRIPT_PROP, script ); if ( !err.ok() ) { return PASSMSG( __FUNCTION__, err ); } // =-=-=-=-=-=-=- // snag a ref to the fco irods::data_object_ptr fco = boost::dynamic_pointer_cast< irods::data_object >( _ctx.fco() ); std::string filename = fco->physical_path(); int mode = fco->mode(); int status = 0; execCmd_t execCmdInp; if ( mode != getDefDirMode() ) { mode = getDefFileMode(); } bzero( &execCmdInp, sizeof( execCmdInp ) ); snprintf( execCmdInp.cmd, sizeof( execCmdInp.cmd ), "%s", script.c_str() ); snprintf( execCmdInp.cmdArgv, sizeof( execCmdInp.cmdArgv ), "chmod '%s' %o", filename.c_str(), mode ); snprintf( execCmdInp.execAddr, sizeof( execCmdInp.execAddr ), "%s", "localhost" ); execCmdOut_t *execCmdOut = NULL; status = _rsExecCmd( &execCmdInp, &execCmdOut ); freeCmdExecOut( execCmdOut ); if ( status < 0 ) { status = UNIV_MSS_CHMOD_ERR - errno; std::stringstream msg; msg << "univ_mss_file_chmod - failed for ["; msg << filename; msg << "]"; return ERROR( status, msg.str() ); } return CODE( status ); } // univ_mss_file_chmod
int createPhyBundleDir( rsComm_t *rsComm, char *bunFilePath, char *outPhyBundleDir, char* hier ) { /* the dir where we put the files to bundle is in phyPath.dir */ snprintf( outPhyBundleDir, MAX_NAME_LEN, "%s.dir", bunFilePath ); int status = mkFileDirR( rsComm, 0, outPhyBundleDir, hier, getDefDirMode() ); if ( status < 0 ) { rodsLog( LOG_ERROR, "mkFileDirR failed in createPhyBundleDir with status %d", status ); } return status; }
int _rsStructFileBundle( rsComm_t* rsComm, structFileExtAndRegInp_t* structFileBundleInp ) { int status; int handleInx; char phyBunDir[MAX_NAME_LEN]; char tmpPath[MAX_NAME_LEN]; int l1descInx; char* dataType = 0; // JMC - backport 4664 openedDataObjInp_t dataObjCloseInp; // =-=-=-=-=-=-=- // create an empty data obj dataObjInp_t dataObjInp; memset( &dataObjInp, 0, sizeof( dataObjInp ) ); dataObjInp.openFlags = O_WRONLY; // =-=-=-=-=-=-=- // get the data type of the structured file dataType = getValByKey( &structFileBundleInp->condInput, DATA_TYPE_KW ); // =-=-=-=-=-=-=- // ensure that the file name will end in .zip, if necessary if ( dataType != NULL && strstr( dataType, ZIP_DT_STR ) != NULL ) { int len = strlen( structFileBundleInp->objPath ); if ( strcmp( &structFileBundleInp->objPath[len - 4], ".zip" ) != 0 ) { strcat( structFileBundleInp->objPath, ".zip" ); } } // =-=-=-=-=-=-=- // capture the object path in the data obj struct rstrcpy( dataObjInp.objPath, structFileBundleInp->objPath, MAX_NAME_LEN ); // =-=-=-=-=-=-=- // replicate the condInput. may have resource input replKeyVal( &structFileBundleInp->condInput, &dataObjInp.condInput ); // =-=-=-=-=-=-=- // open the file if we are in an add operation, otherwise create the new file if ( ( structFileBundleInp->oprType & ADD_TO_TAR_OPR ) != 0 ) { // JMC - backport 4643 l1descInx = rsDataObjOpen( rsComm, &dataObjInp ); } else { l1descInx = rsDataObjCreate( rsComm, &dataObjInp ); } // =-=-=-=-=-=-=- // error check create / open if ( l1descInx < 0 ) { rodsLog( LOG_ERROR, "rsStructFileBundle: rsDataObjCreate of %s error. status = %d", dataObjInp.objPath, l1descInx ); return l1descInx; } // =-=-=-=-=-=-=- // FIXME :: Why, when we replicate them above? clearKeyVal( &dataObjInp.condInput ); // JMC - backport 4637 // ???? l3Close (rsComm, l1descInx); // =-=-=-=-=-=-=- // zip does not like a zero length file as target //L1desc[ l1descInx ].l3descInx = 0; //if( dataType != NULL && strstr( dataType, ZIP_DT_STR ) != NULL ) { // if( ( structFileBundleInp->oprType & ADD_TO_TAR_OPR) == 0 ) { // JMC - backport 4643 // l3Unlink( rsComm, L1desc[l1descInx].dataObjInfo ); // } //} // =-=-=-=-=-=-=- // check object permissions / stat chkObjPermAndStat_t chkObjPermAndStatInp; memset( &chkObjPermAndStatInp, 0, sizeof( chkObjPermAndStatInp ) ); rstrcpy( chkObjPermAndStatInp.objPath, structFileBundleInp->collection, MAX_NAME_LEN ); chkObjPermAndStatInp.flags = CHK_COLL_FOR_BUNDLE_OPR; addKeyVal( &chkObjPermAndStatInp.condInput, RESC_NAME_KW, L1desc[l1descInx].dataObjInfo->rescName ); // =-=-=-=-=-=-=- // get the resc hier string std::string resc_hier; char* resc_hier_ptr = getValByKey( &structFileBundleInp->condInput, RESC_HIER_STR_KW ); if ( !resc_hier_ptr ) { rodsLog( LOG_NOTICE, "_rsStructFileBundle :: RESC_HIER_STR_KW is NULL" ); } else { addKeyVal( &chkObjPermAndStatInp.condInput, RESC_HIER_STR_KW, resc_hier_ptr ); resc_hier = resc_hier_ptr; } status = rsChkObjPermAndStat( rsComm, &chkObjPermAndStatInp ); if ( status < 0 ) { rodsLog( LOG_ERROR, "rsStructFileBundle: rsChkObjPermAndStat of %s error. stat = %d", chkObjPermAndStatInp.objPath, status ); dataObjCloseInp.l1descInx = l1descInx; rsDataObjClose( rsComm, &dataObjCloseInp ); return status; } clearKeyVal( &chkObjPermAndStatInp.condInput ); // =-=-=-=-=-=-=- // create the special hidden directory where the bundling happens createPhyBundleDir( rsComm, L1desc[ l1descInx ].dataObjInfo->filePath, phyBunDir, L1desc[ l1descInx ].dataObjInfo->rescHier ); // =-=-=-=-=-=-=- // build a collection open input structure collInp_t collInp; bzero( &collInp, sizeof( collInp ) ); collInp.flags = RECUR_QUERY_FG | VERY_LONG_METADATA_FG | NO_TRIM_REPL_FG | INCLUDE_CONDINPUT_IN_QUERY; rstrcpy( collInp.collName, structFileBundleInp->collection, MAX_NAME_LEN ); addKeyVal( &collInp.condInput, RESC_NAME_KW, L1desc[ l1descInx ].dataObjInfo->rescName ); rodsLog( LOG_DEBUG, "rsStructFileBundle: calling rsOpenCollection for [%s]", structFileBundleInp->collection ); // =-=-=-=-=-=-=- // open the collection from which we will bundle handleInx = rsOpenCollection( rsComm, &collInp ); if ( handleInx < 0 ) { rodsLog( LOG_ERROR, "rsStructFileBundle: rsOpenCollection of %s error. status = %d", collInp.collName, handleInx ); rmdir( phyBunDir ); return handleInx; } // =-=-=-=-=-=-=- // preserve the collection path? int collLen = 0; if ( ( structFileBundleInp->oprType & PRESERVE_COLL_PATH ) != 0 ) { // =-=-=-=-=-=-=- // preserve the last entry of the coll path char* tmpPtr = collInp.collName; int tmpLen = 0; collLen = 0; // =-=-=-=-=-=-=- // find length to the last '/' while ( *tmpPtr != '\0' ) { if ( *tmpPtr == '/' ) { collLen = tmpLen; } tmpLen++; tmpPtr++; } } else { collLen = strlen( collInp.collName ); } // =-=-=-=-=-=-=- // preserve the collection path? collEnt_t* collEnt = NULL; while ( ( status = rsReadCollection( rsComm, &handleInx, &collEnt ) ) >= 0 ) { if ( NULL == collEnt ) { rodsLog( LOG_ERROR, "rsStructFileBundle: collEnt is NULL" ); continue; } // =-=-=-=-=-=-=- // entry is a data object if ( collEnt->objType == DATA_OBJ_T ) { // =-=-=-=-=-=-=- // filter out any possible replicas that are not on this resource if ( resc_hier != collEnt->resc_hier ) { rodsLog( LOG_DEBUG, "_rsStructFileBundle - skipping [%s] on resc [%s]", collEnt->phyPath, collEnt->resc_hier ); free( collEnt ); collEnt = NULL; continue; } if ( collEnt->collName[collLen] == '\0' ) { snprintf( tmpPath, MAX_NAME_LEN, "%s/%s", phyBunDir, collEnt->dataName ); } else { snprintf( tmpPath, MAX_NAME_LEN, "%s/%s/%s", phyBunDir, collEnt->collName + collLen + 1, collEnt->dataName ); status = mkDirForFilePath( rsComm, strlen( phyBunDir ), tmpPath, collEnt->resc_hier, getDefDirMode() ); if ( status < 0 ) { rodsLog( LOG_ERROR, "mkDirForFilePath failed in _rsStructFileBundle with status %d", status ); free( collEnt ); return status; } } // =-=-=-=-=-=-=- // add a link status = link( collEnt->phyPath, tmpPath ); if ( status < 0 ) { rodsLog( LOG_ERROR, "rsStructFileBundle: link error %s to %s. errno = %d", collEnt->phyPath, tmpPath, errno ); rmLinkedFilesInUnixDir( phyBunDir ); rmdir( phyBunDir ); free( collEnt ); return UNIX_FILE_LINK_ERR - errno; } else { rodsLog( LOG_DEBUG, "_rsStructFileBundle - LINK [%s] on resc [%s]", collEnt->phyPath, collEnt->resc_hier ); } } else { // =-=-=-=-=-=-=- // entry is a collection if ( ( int ) strlen( collEnt->collName ) + 1 <= collLen ) { free( collEnt ); collEnt = NULL; continue; } snprintf( tmpPath, MAX_NAME_LEN, "%s/%s", phyBunDir, collEnt->collName + collLen ); status = mkFileDirR( rsComm, strlen( phyBunDir ), tmpPath, resc_hier.c_str(), getDefDirMode() ); if ( status < 0 ) { rodsLog( LOG_ERROR, "mkFileDirR failed in _rsStructFileBundle with status %d", status ); free( collEnt ); return status; } } // else free( collEnt ); collEnt = NULL; } // while // =-=-=-=-=-=-=- // clean up key vals and close the collection clearKeyVal( &collInp.condInput ); rsCloseCollection( rsComm, &handleInx ); // =-=-=-=-=-=-=- // call the helper function to do the actual bundling status = phyBundle( rsComm, L1desc[l1descInx].dataObjInfo, phyBunDir, collInp.collName, structFileBundleInp->oprType ); // JMC - backport 4643 int savedStatus = 0; if ( status < 0 ) { rodsLog( LOG_ERROR, "rsStructFileBundle: phyBundle of %s error. stat = %d", L1desc[ l1descInx ].dataObjInfo->objPath, status ); L1desc[ l1descInx ].bytesWritten = 0; savedStatus = status; } else { // mark it was written so the size would be adjusted L1desc[ l1descInx ].bytesWritten = 1; } // =-=-=-=-=-=-=- // clean up after the bundle directory rmLinkedFilesInUnixDir( phyBunDir ); rmdir( phyBunDir ); dataObjCloseInp.l1descInx = l1descInx; status = rsDataObjClose( rsComm, &dataObjCloseInp ); if ( status >= 0 ) { return savedStatus; } return status; }
// =-=-=-=-=-=-=-= // _rsFileSyncToArch - this the local version of rsFileSyncToArch. int _rsFileSyncToArch( rsComm_t* _comm, fileStageSyncInp_t* _sync_inp, fileSyncOut_t** _sync_out ) { // =-=-=-=-=-=-=- // XXXX need to check resource permission and vault permission // when RCAT is available // =-=-=-=-=-=-=- // prep if ( _sync_inp->objPath[0] == '\0' ) { std::stringstream msg; msg << __FUNCTION__; msg << " - Empty logical path."; irods::log( LOG_ERROR, msg.str() ); return SYS_INVALID_INPUT_PARAM; } // =-=-=-=-=-=-=- // make call to synctoarch via resource plugin irods::file_object_ptr file_obj( new irods::file_object( _comm, _sync_inp->objPath, _sync_inp->filename, "", 0, _sync_inp->mode, _sync_inp->flags ) ); file_obj->resc_hier( _sync_inp->rescHier ); // =-=-=-=-=-=-=- // pass condInput file_obj->cond_input( _sync_inp->condInput ); irods::error sync_err = fileSyncToArch( _comm, file_obj, _sync_inp->cacheFilename ); if ( !sync_err.ok() ) { if ( getErrno( sync_err.code() ) == ENOENT ) { // =-=-=-=-=-=-=- // the directory does not exist, lets make one int status = mkDirForFilePath( _comm, 0, _sync_inp->filename, _sync_inp->rescHier, getDefDirMode() ); if ( status < 0 ) { rodsLog( LOG_ERROR, "mkDirForFilePath failed in _rsFileSyncToArch with status %d", status ); return status; } } else if ( getErrno( sync_err.code() ) == EEXIST ) { // =-=-=-=-=-=-=- // an empty dir may be there, make the call to rmdir via the resource plugin irods::collection_object_ptr coll_obj( new irods::collection_object( _sync_inp->filename, _sync_inp->rescHier, 0, 0 ) ); coll_obj->cond_input( _sync_inp->condInput ); irods::error rmdir_err = fileRmdir( _comm, coll_obj ); if ( !rmdir_err.ok() ) { std::stringstream msg; msg << "fileRmdir failed for ["; msg << _sync_inp->filename; msg << "]"; irods::error err = PASSMSG( msg.str(), sync_err ); irods::log( err ); } } else { std::stringstream msg; msg << "fileSyncToArch failed for ["; msg << _sync_inp->filename; msg << "]"; irods::error err = PASSMSG( msg.str(), sync_err ); irods::log( err ); return sync_err.code(); } // =-=-=-=-=-=-=- // make call to synctoarch via resource plugin sync_err = fileSyncToArch( _comm, file_obj, _sync_inp->cacheFilename ); if ( !sync_err.ok() ) { std::stringstream msg; msg << "fileSyncToArch failed for ["; msg << _sync_inp->filename; msg << "]"; msg << sync_err.code(); irods::error err = PASSMSG( msg.str(), sync_err ); irods::log( err ); } } // if !sync_err.ok() // =-=-=-=-=-=-=- // has the file name has changed? if ( *_sync_out ) { rstrcpy( ( *_sync_out )->file_name, file_obj->physical_path().c_str(), MAX_NAME_LEN ); } return sync_err.code(); } // _rsFileSyncToArch
int mountFileDir (rsComm_t *rsComm, dataObjInp_t *phyPathRegInp, char *filePath, rescInfo_t *rescInfo) { collInp_t collCreateInp; int rescTypeInx; int status; fileStatInp_t fileStatInp; rodsStat_t *myStat = NULL; rodsObjStat_t *rodsObjStatOut = NULL; if (rsComm->clientUser.authInfo.authFlag < LOCAL_PRIV_USER_AUTH) return(CAT_INSUFFICIENT_PRIVILEGE_LEVEL); status = collStat (rsComm, phyPathRegInp, &rodsObjStatOut); if (status < 0) return status; if (rodsObjStatOut->specColl != NULL) { freeRodsObjStat (rodsObjStatOut); rodsLog (LOG_ERROR, "mountFileDir: %s already mounted", phyPathRegInp->objPath); return (SYS_MOUNT_MOUNTED_COLL_ERR); } freeRodsObjStat (rodsObjStatOut); if (isCollEmpty (rsComm, phyPathRegInp->objPath) == False) { rodsLog (LOG_ERROR, "mountFileDir: collection %s not empty", phyPathRegInp->objPath); return (SYS_COLLECTION_NOT_EMPTY); } memset (&fileStatInp, 0, sizeof (fileStatInp)); rstrcpy (fileStatInp.fileName, filePath, MAX_NAME_LEN); rescTypeInx = rescInfo->rescTypeInx; fileStatInp.fileType = (fileDriverType_t)RescTypeDef[rescTypeInx].driverType; rstrcpy (fileStatInp.addr.hostAddr, rescInfo->rescLoc, NAME_LEN); status = rsFileStat (rsComm, &fileStatInp, &myStat); if (status < 0) { fileMkdirInp_t fileMkdirInp; rodsLog (LOG_NOTICE, "mountFileDir: rsFileStat failed for %s, status = %d, create it", fileStatInp.fileName, status); memset (&fileMkdirInp, 0, sizeof (fileMkdirInp)); rstrcpy (fileMkdirInp.dirName, filePath, MAX_NAME_LEN); fileMkdirInp.fileType = (fileDriverType_t)RescTypeDef[rescTypeInx].driverType; fileMkdirInp.mode = getDefDirMode (); rstrcpy (fileMkdirInp.addr.hostAddr, rescInfo->rescLoc, NAME_LEN); status = rsFileMkdir (rsComm, &fileMkdirInp); if (status < 0) { return (status); } } else if ((myStat->st_mode & S_IFDIR) == 0) { rodsLog (LOG_ERROR, "mountFileDir: phyPath %s is not a directory", fileStatInp.fileName); free (myStat); return (USER_FILE_DOES_NOT_EXIST); } free (myStat); /* mk the collection */ memset (&collCreateInp, 0, sizeof (collCreateInp)); rstrcpy (collCreateInp.collName, phyPathRegInp->objPath, MAX_NAME_LEN); addKeyVal (&collCreateInp.condInput, COLLECTION_TYPE_KW, MOUNT_POINT_STR); addKeyVal (&collCreateInp.condInput, COLLECTION_INFO1_KW, filePath); addKeyVal (&collCreateInp.condInput, COLLECTION_INFO2_KW, rescInfo->rescName); /* try to mod the coll first */ status = rsModColl (rsComm, &collCreateInp); if (status < 0) { /* try to create it */ status = rsRegColl (rsComm, &collCreateInp); } if (status >= 0) { char outLogPath[MAX_NAME_LEN]; int status1; /* see if the phyPath is mapped into a real collection */ if (getLogPathFromPhyPath (filePath, rescInfo, outLogPath) >= 0 && strcmp (outLogPath, phyPathRegInp->objPath) != 0) { /* log path not the same as input objPath */ if (isColl (rsComm, outLogPath, NULL) >= 0) { modAccessControlInp_t modAccessControl; /* it is a real collection. better set the collection * to read-only mode because any modification to files * through this mounted collection can be trouble */ bzero (&modAccessControl, sizeof (modAccessControl)); modAccessControl.accessLevel = "read"; modAccessControl.userName = rsComm->clientUser.userName; modAccessControl.zone = rsComm->clientUser.rodsZone; modAccessControl.path = phyPathRegInp->objPath; status1 = rsModAccessControl(rsComm, &modAccessControl); if (status1 < 0) { rodsLog (LOG_NOTICE, "mountFileDir: rsModAccessControl err for %s, stat = %d", phyPathRegInp->objPath, status1); } } } } return (status); }
int _rsStructFileBundle (rsComm_t *rsComm, structFileExtAndRegInp_t *structFileBundleInp) { int status; dataObjInp_t dataObjInp; openedDataObjInp_t dataObjCloseInp; collInp_t collInp; collEnt_t *collEnt = NULL; int handleInx; int collLen; char phyBunDir[MAX_NAME_LEN]; char tmpPath[MAX_NAME_LEN]; chkObjPermAndStat_t chkObjPermAndStatInp; int l1descInx; int savedStatus = 0; char *dataType; /* open the structured file */ memset (&dataObjInp, 0, sizeof (dataObjInp)); dataType = getValByKey (&structFileBundleInp->condInput, DATA_TYPE_KW); if (dataType != NULL && strstr (dataType, ZIP_DT_STR) != NULL) { /* zipFile type. must end with .zip */ int len = strlen (structFileBundleInp->objPath); if (strcmp (&structFileBundleInp->objPath[len - 4], ".zip") != 0) { strcat (structFileBundleInp->objPath, ".zip"); } } rstrcpy (dataObjInp.objPath, structFileBundleInp->objPath, MAX_NAME_LEN); /* replicate the condInput. may have resource input */ replKeyVal (&structFileBundleInp->condInput, &dataObjInp.condInput); dataObjInp.openFlags = O_WRONLY; if ((structFileBundleInp->oprType & ADD_TO_TAR_OPR) != 0) { l1descInx = rsDataObjOpen (rsComm, &dataObjInp); } else { l1descInx = rsDataObjCreate (rsComm, &dataObjInp); } if (l1descInx < 0) { rodsLog (LOG_ERROR, "rsStructFileBundle: rsDataObjCreate of %s error. status = %d", dataObjInp.objPath, l1descInx); return (l1descInx); } clearKeyVal (&dataObjInp.condInput); l3Close (rsComm, l1descInx); L1desc[l1descInx].l3descInx = 0; /* zip does not like a zero length file as target */ if ((structFileBundleInp->oprType & ADD_TO_TAR_OPR) == 0) l3Unlink (rsComm, L1desc[l1descInx].dataObjInfo); memset (&chkObjPermAndStatInp, 0, sizeof (chkObjPermAndStatInp)); rstrcpy (chkObjPermAndStatInp.objPath, structFileBundleInp->collection, MAX_NAME_LEN); chkObjPermAndStatInp.flags = CHK_COLL_FOR_BUNDLE_OPR; addKeyVal (&chkObjPermAndStatInp.condInput, RESC_NAME_KW, L1desc[l1descInx].dataObjInfo->rescName); status = rsChkObjPermAndStat (rsComm, &chkObjPermAndStatInp); clearKeyVal (&chkObjPermAndStatInp.condInput); if (status < 0) { rodsLog (LOG_ERROR, "rsStructFileBundle: rsChkObjPermAndStat of %s error. stat = %d", chkObjPermAndStatInp.objPath, status); dataObjCloseInp.l1descInx = l1descInx; rsDataObjClose (rsComm, &dataObjCloseInp); return (status); } createPhyBundleDir (rsComm, L1desc[l1descInx].dataObjInfo->filePath, phyBunDir); bzero (&collInp, sizeof (collInp)); rstrcpy (collInp.collName, structFileBundleInp->collection, MAX_NAME_LEN); collInp.flags = RECUR_QUERY_FG | VERY_LONG_METADATA_FG | NO_TRIM_REPL_FG | INCLUDE_CONDINPUT_IN_QUERY; addKeyVal (&collInp.condInput, RESC_NAME_KW, L1desc[l1descInx].dataObjInfo->rescName); handleInx = rsOpenCollection (rsComm, &collInp); if (handleInx < 0) { rodsLog (LOG_ERROR, "rsStructFileBundle: rsOpenCollection of %s error. status = %d", collInp.collName, handleInx); rmdir (phyBunDir); return (handleInx); } if ((structFileBundleInp->oprType & PRESERVE_COLL_PATH) != 0) { /* preserver the last entry of the coll path */ char *tmpPtr = collInp.collName; int tmpLen = 0; collLen = 0; /* find length to the last '/' */ while (*tmpPtr != '\0') { if (*tmpPtr == '/') collLen = tmpLen; tmpLen++; tmpPtr++; } } else { collLen = strlen (collInp.collName); } while ((status = rsReadCollection (rsComm, &handleInx, &collEnt)) >= 0) { if (collEnt->objType == DATA_OBJ_T) { if (collEnt->collName[collLen] == '\0') { snprintf (tmpPath, MAX_NAME_LEN, "%s/%s", phyBunDir, collEnt->dataName); } else { snprintf (tmpPath, MAX_NAME_LEN, "%s/%s/%s", phyBunDir, collEnt->collName + collLen + 1, collEnt->dataName); mkDirForFilePath (UNIX_FILE_TYPE, rsComm, phyBunDir, tmpPath, getDefDirMode ()); } /* add a link */ status = link (collEnt->phyPath, tmpPath); if (status < 0) { rodsLog (LOG_ERROR, "rsStructFileBundle: link error %s to %s. errno = %d", collEnt->phyPath, tmpPath, errno); rmLinkedFilesInUnixDir (phyBunDir); rmdir (phyBunDir); return (UNIX_FILE_LINK_ERR - errno); } } else { /* a collection */ if ((int) strlen (collEnt->collName) + 1 <= collLen) { free (collEnt); continue; } snprintf (tmpPath, MAX_NAME_LEN, "%s/%s", phyBunDir, collEnt->collName + collLen); mkdirR (phyBunDir, tmpPath, getDefDirMode ()); } if (collEnt != NULL) { free (collEnt); collEnt = NULL; } } clearKeyVal (&collInp.condInput); rsCloseCollection (rsComm, &handleInx); status = phyBundle (rsComm, L1desc[l1descInx].dataObjInfo, phyBunDir, collInp.collName, structFileBundleInp->oprType); if (status < 0) { rodsLog (LOG_ERROR, "rsStructFileBundle: phyBundle of %s error. stat = %d", L1desc[l1descInx].dataObjInfo->objPath, status); L1desc[l1descInx].bytesWritten = 0; savedStatus = status; } else { /* mark it was written so the size would be adjusted */ L1desc[l1descInx].bytesWritten = 1; } rmLinkedFilesInUnixDir (phyBunDir); rmdir (phyBunDir); dataObjCloseInp.l1descInx = l1descInx; status = rsDataObjClose (rsComm, &dataObjCloseInp); if (status >= 0) return savedStatus; else return (status); }
int chkCollForExtAndReg (rsComm_t *rsComm, char *collection, rodsObjStat_t **rodsObjStatOut) { dataObjInp_t dataObjInp; int status; rodsObjStat_t *myRodsObjStat = NULL; bzero (&dataObjInp, sizeof (dataObjInp)); rstrcpy (dataObjInp.objPath, collection, MAX_NAME_LEN); #if 0 /* allow mounted coll */ status = collStat (rsComm, &dataObjInp, &myRodsObjStat); #endif status = collStatAllKinds (rsComm, &dataObjInp, &myRodsObjStat); #if 0 if (status == CAT_NO_ROWS_FOUND || status == OBJ_PATH_DOES_NOT_EXIST || status == USER_FILE_DOES_NOT_EXIST) { #endif if (status < 0) { status = rsMkCollR (rsComm, "/", collection); if (status < 0) { rodsLog (LOG_ERROR, "chkCollForExtAndReg: rsMkCollR of %s error. status = %d", collection, status); return (status); } else { #if 0 /* allow mounted coll */ status = collStat (rsComm, &dataObjInp, &myRodsObjStat); #endif status = collStatAllKinds (rsComm, &dataObjInp, &myRodsObjStat); } } if (status < 0) { rodsLog (LOG_ERROR, "chkCollForExtAndReg: collStat of %s error. status = %d", dataObjInp.objPath, status); return (status); } else if (myRodsObjStat->specColl != NULL && myRodsObjStat->specColl->collClass != MOUNTED_COLL) { /* only do mounted coll */ freeRodsObjStat (myRodsObjStat); rodsLog (LOG_ERROR, "chkCollForExtAndReg: %s is a struct file collection", dataObjInp.objPath); return (SYS_STRUCT_FILE_INMOUNTED_COLL); } if (myRodsObjStat->specColl == NULL) { status = checkCollAccessPerm (rsComm, collection, ACCESS_DELETE_OBJECT); } else { status = checkCollAccessPerm (rsComm, myRodsObjStat->specColl->collection, ACCESS_DELETE_OBJECT); } if (status < 0) { rodsLog (LOG_ERROR, "chkCollForExtAndReg: no permission to write %s, status = %d", collection, status); freeRodsObjStat (myRodsObjStat); } else { if (rodsObjStatOut != NULL) { *rodsObjStatOut = myRodsObjStat; } else { freeRodsObjStat (myRodsObjStat); } } return (status); } /* regUnbunSubfiles - non bulk version of registering all files in phyBunDir * to the collection. Valid values for flags are: * FORCE_FLAG_FLAG. */ int regUnbunSubfiles (rsComm_t *rsComm, rescInfo_t *rescInfo, char *rescGroupName, char *collection, char *phyBunDir, int flags, genQueryOut_t *attriArray) { #ifndef USE_BOOST_FS DIR *dirPtr; struct dirent *myDirent; struct stat statbuf; #endif char subfilePath[MAX_NAME_LEN]; char subObjPath[MAX_NAME_LEN]; dataObjInp_t dataObjInp; int status; int savedStatus = 0; rodsLong_t st_size; #ifdef USE_BOOST_FS path srcDirPath (phyBunDir); if (!exists(srcDirPath) || !is_directory(srcDirPath)) { #else dirPtr = opendir (phyBunDir); if (dirPtr == NULL) { #endif rodsLog (LOG_ERROR, "regUnbunphySubfiles: opendir error for %s, errno = %d", phyBunDir, errno); return (UNIX_FILE_OPENDIR_ERR - errno); } bzero (&dataObjInp, sizeof (dataObjInp)); #ifdef USE_BOOST_FS directory_iterator end_itr; // default construction yields past-the-end for (directory_iterator itr(srcDirPath); itr != end_itr;++itr) { path p = itr->path(); snprintf (subfilePath, MAX_NAME_LEN, "%s", p.c_str ()); #else while ((myDirent = readdir (dirPtr)) != NULL) { if (strcmp (myDirent->d_name, ".") == 0 || strcmp (myDirent->d_name, "..") == 0) { continue; } snprintf (subfilePath, MAX_NAME_LEN, "%s/%s", phyBunDir, myDirent->d_name); #endif #ifdef USE_BOOST_FS if (!exists (p)) { #else status = lstat (subfilePath, &statbuf); if (status != 0) { #endif rodsLog (LOG_ERROR, "regUnbunphySubfiles: stat error for %s, errno = %d", subfilePath, errno); savedStatus = UNIX_FILE_STAT_ERR - errno; unlink (subfilePath); continue; } #ifdef USE_BOOST_FS if (is_symlink (p)) { #else if ((statbuf.st_mode & S_IFLNK) == S_IFLNK) { #endif rodsLogError (LOG_ERROR, SYMLINKED_BUNFILE_NOT_ALLOWED, "regUnbunSubfiles: %s is a symlink", subfilePath); savedStatus = SYMLINKED_BUNFILE_NOT_ALLOWED; continue; } #ifdef USE_BOOST_FS path childPath = p.filename(); snprintf (subObjPath, MAX_NAME_LEN, "%s/%s", collection, childPath.c_str()); if (is_directory (p)) { #else snprintf (subObjPath, MAX_NAME_LEN, "%s/%s", collection, myDirent->d_name); if ((statbuf.st_mode & S_IFDIR) != 0) { #endif status = rsMkCollR (rsComm, "/", subObjPath); if (status < 0) { rodsLog (LOG_ERROR, "regUnbunSubfiles: rsMkCollR of %s error. status = %d", subObjPath, status); savedStatus = status; continue; } status = regUnbunSubfiles (rsComm, rescInfo, rescGroupName, subObjPath, subfilePath, flags, attriArray); if (status < 0) { rodsLog (LOG_ERROR, "regUnbunSubfiles: regUnbunSubfiles of %s error. status=%d", subObjPath, status); savedStatus = status; continue; } #ifdef USE_BOOST_FS } else if (is_regular_file (p)) { st_size = file_size (p); #else } else if ((statbuf.st_mode & S_IFREG) != 0) { st_size = statbuf.st_size; #endif status = regSubfile (rsComm, rescInfo, rescGroupName, subObjPath, subfilePath, st_size, flags); unlink (subfilePath); if (status < 0) { rodsLog (LOG_ERROR, "regUnbunSubfiles: regSubfile of %s error. status=%d", subObjPath, status); savedStatus = status; continue; } } } #ifndef USE_BOOST_FS closedir (dirPtr); #endif rmdir (phyBunDir); return savedStatus; } int regSubfile (rsComm_t *rsComm, rescInfo_t *rescInfo, char *rescGroupName, char *subObjPath, char *subfilePath, rodsLong_t dataSize, int flags) { dataObjInfo_t dataObjInfo; dataObjInp_t dataObjInp; #ifndef USE_BOOST_FS struct stat statbuf; #endif int status; int modFlag = 0; bzero (&dataObjInp, sizeof (dataObjInp)); bzero (&dataObjInfo, sizeof (dataObjInfo)); rstrcpy (dataObjInp.objPath, subObjPath, MAX_NAME_LEN); rstrcpy (dataObjInfo.objPath, subObjPath, MAX_NAME_LEN); rstrcpy (dataObjInfo.rescName, rescInfo->rescName, NAME_LEN); rstrcpy (dataObjInfo.dataType, "generic", NAME_LEN); dataObjInfo.rescInfo = rescInfo; rstrcpy (dataObjInfo.rescGroupName, rescGroupName, NAME_LEN); dataObjInfo.dataSize = dataSize; status = getFilePathName (rsComm, &dataObjInfo, &dataObjInp); if (status < 0) { rodsLog (LOG_ERROR, "regSubFile: getFilePathName err for %s. status = %d", dataObjInp.objPath, status); return (status); } #ifdef USE_BOOST_FS path p (dataObjInfo.filePath); if (exists (p)) { if (is_directory (p)) { #else status = stat (dataObjInfo.filePath, &statbuf); if (status == 0 || errno != ENOENT) { if ((statbuf.st_mode & S_IFDIR) != 0) { #endif return SYS_PATH_IS_NOT_A_FILE; } if (chkOrphanFile (rsComm, dataObjInfo.filePath, rescInfo->rescName, &dataObjInfo) > 0) { /* an orphan file. just rename it */ fileRenameInp_t fileRenameInp; bzero (&fileRenameInp, sizeof (fileRenameInp)); rstrcpy (fileRenameInp.oldFileName, dataObjInfo.filePath, MAX_NAME_LEN); status = renameFilePathToNewDir (rsComm, ORPHAN_DIR, &fileRenameInp, rescInfo, 1); if (status < 0) { rodsLog (LOG_ERROR, "regSubFile: renameFilePathToNewDir err for %s. status = %d", fileRenameInp.oldFileName, status); return (status); } } else { /* not an orphan file */ if ((flags & FORCE_FLAG_FLAG) != 0 && dataObjInfo.dataId > 0 && strcmp (dataObjInfo.objPath, subObjPath) == 0) { /* overwrite the current file */ modFlag = 1; unlink (dataObjInfo.filePath); } else { status = SYS_COPY_ALREADY_IN_RESC; rodsLog (LOG_ERROR, "regSubFile: phypath %s is already in use. status = %d", dataObjInfo.filePath, status); return (status); } } } /* make the necessary dir */ mkDirForFilePath (UNIX_FILE_TYPE, rsComm, "/", dataObjInfo.filePath, getDefDirMode ()); /* add a link */ #ifndef windows_platform /* Windows does not support link */ status = link (subfilePath, dataObjInfo.filePath); if (status < 0) { rodsLog (LOG_ERROR, "regSubFile: link error %s to %s. errno = %d", subfilePath, dataObjInfo.filePath, errno); return (UNIX_FILE_LINK_ERR - errno); } #endif if (modFlag == 0) { status = svrRegDataObj (rsComm, &dataObjInfo); } else { char tmpStr[MAX_NAME_LEN]; modDataObjMeta_t modDataObjMetaInp; keyValPair_t regParam; bzero (&modDataObjMetaInp, sizeof (modDataObjMetaInp)); bzero (®Param, sizeof (regParam)); snprintf (tmpStr, MAX_NAME_LEN, "%lld", dataSize); addKeyVal (®Param, DATA_SIZE_KW, tmpStr); addKeyVal (®Param, ALL_REPL_STATUS_KW, tmpStr); snprintf (tmpStr, MAX_NAME_LEN, "%d", (int) time (NULL)); addKeyVal (®Param, DATA_MODIFY_KW, tmpStr); modDataObjMetaInp.dataObjInfo = &dataObjInfo; modDataObjMetaInp.regParam = ®Param; status = rsModDataObjMeta (rsComm, &modDataObjMetaInp); clearKeyVal (®Param); } if (status < 0) { rodsLog (LOG_ERROR, "regSubFile: svrRegDataObj of %s. errno = %d", dataObjInfo.objPath, errno); unlink (dataObjInfo.filePath); } else { ruleExecInfo_t rei; dataObjInp_t dataObjInp; bzero (&dataObjInp, sizeof (dataObjInp)); rstrcpy (dataObjInp.objPath, dataObjInfo.objPath, MAX_NAME_LEN); initReiWithDataObjInp (&rei, rsComm, &dataObjInp); rei.doi = &dataObjInfo; rei.status = applyRule ("acPostProcForTarFileReg", NULL, &rei, NO_SAVE_REI); if (rei.status < 0) { rodsLogError (LOG_ERROR, rei.status, "regSubFile: acPostProcForTarFileReg error for %s. status = %d", dataObjInfo.objPath); } } return status; }