00001
00002
00003
00004
00005
00006
00007
00008 #include "apiHeaderAll.h"
00009 #include "objMetaOpr.h"
00010 #include "collection.h"
00011 #include "dataObjOpr.h"
00012 #include "resource.h"
00013 #include "specColl.h"
00014 #include "physPath.h"
00015 #include "objStat.h"
00016 #include "miscServerFunct.h"
00017 #include "fileOpr.h"
00018 #include "rcGlobalExtern.h"
00019 #include "reGlobalsExtern.h"
00020 #include "structFileExtAndReg.h"
00021
00022
00023
00024 #include "eirods_resource_redirect.h"
00025 #include "eirods_stacktrace.h"
00026 #include "eirods_resource_backport.h"
00027 #include "eirods_file_object.h"
00028
00029 int
00030 rsStructFileExtAndReg (rsComm_t *rsComm,
00031 structFileExtAndRegInp_t *structFileExtAndRegInp)
00032 {
00033 int status;
00034 dataObjInp_t dataObjInp;
00035 openedDataObjInp_t dataObjCloseInp;
00036 dataObjInfo_t *dataObjInfo;
00037 int l1descInx;
00038 rescInfo_t *rescInfo;
00039 char *rescGroupName;
00040 int remoteFlag;
00041 rodsServerHost_t *rodsServerHost;
00042 char phyBunDir[MAX_NAME_LEN];
00043 int flags = 0;
00044
00045 specCollCache_t *specCollCache = NULL;
00046
00047 resolveLinkedPath (rsComm, structFileExtAndRegInp->objPath, &specCollCache,
00048 &structFileExtAndRegInp->condInput);
00049
00050 resolveLinkedPath (rsComm, structFileExtAndRegInp->collection,
00051 &specCollCache, NULL);
00052
00053 if (!isSameZone (structFileExtAndRegInp->objPath,
00054 structFileExtAndRegInp->collection))
00055 return SYS_CROSS_ZONE_MV_NOT_SUPPORTED;
00056
00057 memset (&dataObjInp, 0, sizeof (dataObjInp));
00058 rstrcpy (dataObjInp.objPath, structFileExtAndRegInp->objPath,
00059 MAX_NAME_LEN);
00060
00061
00062 replKeyVal (&structFileExtAndRegInp->condInput, &dataObjInp.condInput);
00063 dataObjInp.openFlags = O_RDONLY;
00064
00065 remoteFlag = getAndConnRemoteZone (rsComm, &dataObjInp, &rodsServerHost,
00066 REMOTE_OPEN);
00067
00068 if (remoteFlag < 0) {
00069 return (remoteFlag);
00070 } else if (remoteFlag == REMOTE_HOST) {
00071 status = rcStructFileExtAndReg (rodsServerHost->conn,
00072 structFileExtAndRegInp);
00073 return status;
00074 }
00075
00076
00077
00078
00079
00080 std::string hier;
00081 int local = LOCAL_HOST;
00082 rodsServerHost_t* host = 0;
00083 if( getValByKey( &dataObjInp.condInput, RESC_HIER_STR_KW ) == NULL ) {
00084 eirods::error ret = eirods::resource_redirect( eirods::EIRODS_OPEN_OPERATION, rsComm,
00085 &dataObjInp, hier, host, local );
00086 if( !ret.ok() ) {
00087 std::stringstream msg;
00088 msg << "rsStructFileExtAndReg :: failed in eirods::resource_redirect for [";
00089 msg << dataObjInp.objPath << "]";
00090 eirods::log( PASSMSG( msg.str(), ret ) );
00091 return ret.code();
00092 }
00093
00094
00095
00096
00097 addKeyVal( &dataObjInp.condInput, RESC_HIER_STR_KW, hier.c_str() );
00098
00099 }
00100
00101
00102 addKeyVal (&dataObjInp.condInput, NO_OPEN_FLAG_KW, "");
00103 l1descInx = _rsDataObjOpen (rsComm, &dataObjInp);
00104
00105 if (l1descInx < 0) {
00106 rodsLog (LOG_ERROR,
00107 "rsStructFileExtAndReg: _rsDataObjOpen of %s error. status = %d",
00108 dataObjInp.objPath, l1descInx);
00109 return (l1descInx);
00110 }
00111
00112 rescInfo = L1desc[l1descInx].dataObjInfo->rescInfo;
00113 rescGroupName = L1desc[l1descInx].dataObjInfo->rescGroupName;
00114
00115
00116
00117
00118
00119
00120
00121 bzero (&dataObjCloseInp, sizeof (dataObjCloseInp));
00122 dataObjCloseInp.l1descInx = l1descInx;
00123
00124 if( local == REMOTE_HOST ) {
00125 addKeyVal (&structFileExtAndRegInp->condInput, RESC_NAME_KW,
00126 rescInfo->rescName);
00127
00128
00129
00130
00131 status = rcStructFileExtAndReg( host->conn, structFileExtAndRegInp );
00132 rsDataObjClose (rsComm, &dataObjCloseInp);
00133
00134 return status;
00135 }
00136
00137 status = chkCollForExtAndReg ( rsComm, structFileExtAndRegInp->collection, NULL );
00138
00139 if (status < 0) return status;
00140
00141
00142 dataObjInfo = L1desc[l1descInx].dataObjInfo;
00143 std::string rescHier = dataObjInfo->rescHier;
00144
00145 createPhyBundleDir (rsComm, dataObjInfo->filePath, phyBunDir);
00146
00147 status = unbunPhyBunFile( rsComm, dataObjInp.objPath, rescInfo,
00148 dataObjInfo->filePath, phyBunDir, dataObjInfo->dataType, 0,
00149 rescHier.c_str() );
00150
00151 if (status == SYS_DIR_IN_VAULT_NOT_EMPTY) {
00152
00153 char tmp[MAX_NAME_LEN];
00154 strcpy( tmp, phyBunDir );
00155 snprintf( phyBunDir, MAX_NAME_LEN, "%s.%-d", tmp, (int) random () );
00156 status = unbunPhyBunFile( rsComm, dataObjInp.objPath, rescInfo,
00157 dataObjInfo->filePath, phyBunDir, dataObjInfo->dataType, 0,
00158 rescHier.c_str() );
00159 }
00160
00161 if (status < 0) {
00162 rodsLog (LOG_ERROR,
00163 "rsStructFileExtAndReg:unbunPhyBunFile err for %s to dir %s.stat=%d",
00164 dataObjInfo->filePath, phyBunDir, status);
00165 rsDataObjClose (rsComm, &dataObjCloseInp);
00166 return status;
00167 }
00168
00169 if (getValByKey (&structFileExtAndRegInp->condInput, FORCE_FLAG_KW)
00170 != NULL) {
00171 flags = flags | FORCE_FLAG_FLAG;
00172 }
00173 if (getValByKey (&structFileExtAndRegInp->condInput, BULK_OPR_KW)
00174 != NULL) {
00175
00176 status = bulkRegUnbunSubfiles (rsComm, rescInfo, rescHier, rescGroupName,
00177 structFileExtAndRegInp->collection, phyBunDir, flags, NULL);
00178 } else {
00179 status = regUnbunSubfiles (rsComm, rescInfo, dataObjInfo->rescHier, rescGroupName,
00180 structFileExtAndRegInp->collection, phyBunDir, flags, NULL);
00181 }
00182
00183 if (status == CAT_NO_ROWS_FOUND) {
00184
00185 status = 0;
00186 } else if (status < 0) {
00187 rodsLog (LOG_ERROR,
00188 "_rsUnbunAndRegPhyBunfile: rsStructFileExtAndReg for dir %s.stat=%d",
00189 phyBunDir, status);
00190 }
00191 rsDataObjClose (rsComm, &dataObjCloseInp);
00192
00193 return status;
00194 }
00195
00196 int
00197 chkCollForExtAndReg (rsComm_t *rsComm, char *collection,
00198 rodsObjStat_t **rodsObjStatOut)
00199 {
00200 dataObjInp_t dataObjInp;
00201 int status;
00202 rodsObjStat_t *myRodsObjStat = NULL;
00203
00204 bzero (&dataObjInp, sizeof (dataObjInp));
00205 rstrcpy (dataObjInp.objPath, collection, MAX_NAME_LEN);
00206 status = collStatAllKinds (rsComm, &dataObjInp, &myRodsObjStat);
00207 if (status < 0) {
00208 status = rsMkCollR (rsComm, "/", collection);
00209 if (status < 0) {
00210 rodsLog (LOG_ERROR,
00211 "chkCollForExtAndReg: rsMkCollR of %s error. status = %d",
00212 collection, status);
00213 return (status);
00214 } else {
00215 status = collStatAllKinds (rsComm, &dataObjInp, &myRodsObjStat);
00216 }
00217 }
00218
00219 if (status < 0 || NULL == myRodsObjStat ) {
00220 rodsLog (LOG_ERROR,
00221 "chkCollForExtAndReg: collStat of %s error. status = %d",
00222 dataObjInp.objPath, status);
00223 return (status);
00224 } else if (myRodsObjStat->specColl != NULL &&
00225 myRodsObjStat->specColl->collClass != MOUNTED_COLL) {
00226
00227 freeRodsObjStat (myRodsObjStat);
00228 rodsLog (LOG_ERROR,
00229 "chkCollForExtAndReg: %s is a struct file collection",
00230 dataObjInp.objPath);
00231 return (SYS_STRUCT_FILE_INMOUNTED_COLL);
00232 }
00233
00234 if (myRodsObjStat->specColl == NULL) {
00235 status = checkCollAccessPerm (rsComm, collection, ACCESS_DELETE_OBJECT);
00236 } else {
00237 status = checkCollAccessPerm (rsComm,
00238 myRodsObjStat->specColl->collection, ACCESS_DELETE_OBJECT);
00239 }
00240
00241 if (status < 0) {
00242 rodsLog (LOG_ERROR,
00243 "chkCollForExtAndReg: no permission to write %s, status = %d",
00244 collection, status);
00245 freeRodsObjStat (myRodsObjStat);
00246 } else {
00247 if (rodsObjStatOut != NULL) {
00248 *rodsObjStatOut = myRodsObjStat;
00249 } else {
00250 freeRodsObjStat (myRodsObjStat);
00251 }
00252 }
00253 return (status);
00254 }
00255
00256
00257
00258
00259
00260
00261 int
00262 regUnbunSubfiles (rsComm_t *rsComm, rescInfo_t *rescInfo, const char* rescHier, char *rescGroupName,
00263 char *collection, char *phyBunDir, int flags, genQueryOut_t *attriArray)
00264 {
00265 char subfilePath[MAX_NAME_LEN];
00266 char subObjPath[MAX_NAME_LEN];
00267 dataObjInp_t dataObjInp;
00268 int status;
00269 int savedStatus = 0;
00270 rodsLong_t st_size;
00271
00272 path srcDirPath (phyBunDir);
00273 if (!exists(srcDirPath) || !is_directory(srcDirPath)) {
00274 rodsLog (LOG_ERROR,
00275 "regUnbunphySubfiles: opendir error for %s, errno = %d",
00276 phyBunDir, errno);
00277 return (UNIX_FILE_OPENDIR_ERR - errno);
00278 }
00279 bzero (&dataObjInp, sizeof (dataObjInp));
00280 directory_iterator end_itr;
00281 for (directory_iterator itr(srcDirPath); itr != end_itr;++itr) {
00282 path p = itr->path();
00283 snprintf (subfilePath, MAX_NAME_LEN, "%s",
00284 p.c_str ());
00285 if (!exists (p)) {
00286 rodsLog (LOG_ERROR,
00287 "regUnbunphySubfiles: stat error for %s, errno = %d",
00288 subfilePath, errno);
00289 savedStatus = UNIX_FILE_STAT_ERR - errno;
00290 unlink (subfilePath);
00291 continue;
00292 }
00293
00294
00295 if (is_symlink (p)) {
00296 rodsLogError (LOG_ERROR, SYMLINKED_BUNFILE_NOT_ALLOWED,
00297 "regUnbunSubfiles: %s is a symlink",
00298 subfilePath);
00299 savedStatus = SYMLINKED_BUNFILE_NOT_ALLOWED;
00300 continue;
00301 }
00302
00303 path childPath = p.filename();
00304 snprintf (subObjPath, MAX_NAME_LEN, "%s/%s",
00305 collection, childPath.c_str());
00306
00307 if (is_directory (p)) {
00308 status = rsMkCollR (rsComm, "/", subObjPath);
00309 if (status < 0) {
00310 rodsLog (LOG_ERROR,
00311 "regUnbunSubfiles: rsMkCollR of %s error. status = %d",
00312 subObjPath, status);
00313 savedStatus = status;
00314 continue;
00315 }
00316 status = regUnbunSubfiles (rsComm, rescInfo, rescHier, rescGroupName,
00317 subObjPath, subfilePath, flags, attriArray);
00318 if (status < 0) {
00319 rodsLog (LOG_ERROR,
00320 "regUnbunSubfiles: regUnbunSubfiles of %s error. status=%d",
00321 subObjPath, status);
00322 savedStatus = status;
00323 continue;
00324 }
00325 } else if (is_regular_file (p)) {
00326 st_size = file_size (p);
00327 status = regSubfile (rsComm, rescInfo, rescHier, rescGroupName,
00328 subObjPath, subfilePath, st_size, flags);
00329 unlink (subfilePath);
00330 if (status < 0) {
00331 rodsLog (LOG_ERROR,
00332 "regUnbunSubfiles: regSubfile of %s error. status=%d",
00333 subObjPath, status);
00334 savedStatus = status;
00335 continue;
00336 }
00337 }
00338 }
00339 rmdir (phyBunDir);
00340 return savedStatus;
00341 }
00342
00343 int
00344 regSubfile (rsComm_t *rsComm, rescInfo_t *rescInfo, const char* rescHier, char *rescGroupName,
00345 char *subObjPath, char *subfilePath, rodsLong_t dataSize, int flags)
00346 {
00347 dataObjInfo_t dataObjInfo;
00348 dataObjInp_t dataObjInp;
00349 int status;
00350 int modFlag = 0;
00351
00352 bzero (&dataObjInp, sizeof (dataObjInp));
00353 bzero (&dataObjInfo, sizeof (dataObjInfo));
00354 rstrcpy (dataObjInp.objPath, subObjPath, MAX_NAME_LEN);
00355 rstrcpy (dataObjInfo.objPath, subObjPath, MAX_NAME_LEN);
00356 rstrcpy (dataObjInfo.rescName, rescInfo->rescName, NAME_LEN);
00357 rstrcpy (dataObjInfo.rescHier, rescHier, MAX_NAME_LEN);
00358 rstrcpy (dataObjInfo.dataType, "generic", NAME_LEN);
00359 dataObjInfo.rescInfo = new rescInfo_t;
00360 memcpy( dataObjInfo.rescInfo, rescInfo, sizeof( rescInfo_t ) );
00361 rstrcpy (dataObjInfo.rescGroupName, rescGroupName, NAME_LEN);
00362 dataObjInfo.dataSize = dataSize;
00363 dataObjInfo.replStatus = 1;
00364
00365 status = getFilePathName (rsComm, &dataObjInfo, &dataObjInp);
00366 if (status < 0) {
00367 rodsLog (LOG_ERROR,
00368 "regSubFile: getFilePathName err for %s. status = %d",
00369 dataObjInp.objPath, status);
00370 return (status);
00371 }
00372
00373 path p (dataObjInfo.filePath);
00374 if (exists (p)) {
00375 if (is_directory (p)) {
00376 return SYS_PATH_IS_NOT_A_FILE;
00377 }
00378
00379 if (chkOrphanFile (rsComm, dataObjInfo.filePath, rescInfo->rescName,
00380 &dataObjInfo) > 0) {
00381
00382 fileRenameInp_t fileRenameInp;
00383 bzero (&fileRenameInp, sizeof (fileRenameInp));
00384 rstrcpy (fileRenameInp.oldFileName, dataObjInfo.filePath,
00385 MAX_NAME_LEN);
00386 status = renameFilePathToNewDir (rsComm, ORPHAN_DIR,
00387 &fileRenameInp, rescInfo, 1);
00388 if (status < 0) {
00389 rodsLog (LOG_ERROR,
00390 "regSubFile: renameFilePathToNewDir err for %s. status = %d",
00391 fileRenameInp.oldFileName, status);
00392 return (status);
00393 }
00394 } else {
00395
00396 if ((flags & FORCE_FLAG_FLAG) != 0 && dataObjInfo.dataId > 0 &&
00397 strcmp (dataObjInfo.objPath, subObjPath) == 0) {
00398
00399 modFlag = 1;
00400 unlink (dataObjInfo.filePath);
00401 } else {
00402 status = SYS_COPY_ALREADY_IN_RESC;
00403 rodsLog (LOG_ERROR,
00404 "regSubFile: phypath %s is already in use. status = %d",
00405 dataObjInfo.filePath, status);
00406 return (status);
00407 }
00408 }
00409 }
00410
00411 mkDirForFilePath (rsComm, "/", dataObjInfo.filePath, getDefDirMode ());
00412
00413
00414 #ifndef windows_platform
00415 status = link (subfilePath, dataObjInfo.filePath);
00416 if (status < 0) {
00417 rodsLog (LOG_ERROR,
00418 "regSubFile: link error %s to %s. errno = %d",
00419 subfilePath, dataObjInfo.filePath, errno);
00420 return (UNIX_FILE_LINK_ERR - errno);
00421 }
00422 #endif
00423
00424 if (modFlag == 0) {
00425 status = svrRegDataObj (rsComm, &dataObjInfo);
00426
00427
00428
00429 eirods::file_object_ptr file_obj(
00430 new eirods::file_object(
00431 rsComm,
00432 &dataObjInfo ) );
00433
00434 eirods::error ret = fileModified(rsComm, file_obj);
00435 if(!ret.ok()) {
00436 std::stringstream msg;
00437 msg << " Failed to signal resource that the data object \"";
00438 msg << dataObjInfo.objPath;
00439 msg << " was modified.";
00440 ret = PASSMSG(msg.str(), ret);
00441 eirods::log(ret);
00442 status = ret.code();
00443 }
00444
00445 } else {
00446 char tmpStr[MAX_NAME_LEN];
00447 modDataObjMeta_t modDataObjMetaInp;
00448 keyValPair_t regParam;
00449
00450 bzero (&modDataObjMetaInp, sizeof (modDataObjMetaInp));
00451 bzero (®Param, sizeof (regParam));
00452 snprintf (tmpStr, MAX_NAME_LEN, "%lld", dataSize);
00453 addKeyVal (®Param, DATA_SIZE_KW, tmpStr);
00454 addKeyVal (®Param, ALL_REPL_STATUS_KW, tmpStr);
00455 snprintf (tmpStr, MAX_NAME_LEN, "%d", (int) time (NULL));
00456 addKeyVal (®Param, DATA_MODIFY_KW, tmpStr);
00457
00458 modDataObjMetaInp.dataObjInfo = &dataObjInfo;
00459 modDataObjMetaInp.regParam = ®Param;
00460
00461
00462
00463 status = rsModDataObjMeta (rsComm, &modDataObjMetaInp);
00464
00465 clearKeyVal (®Param);
00466 }
00467
00468 if (status < 0) {
00469 rodsLog (LOG_ERROR,
00470 "regSubFile: svrRegDataObj of %s. errno = %d",
00471 dataObjInfo.objPath, errno);
00472 unlink (dataObjInfo.filePath);
00473 } else {
00474 ruleExecInfo_t rei;
00475 dataObjInp_t dataObjInp;
00476 bzero (&dataObjInp, sizeof (dataObjInp));
00477 rstrcpy (dataObjInp.objPath, dataObjInfo.objPath, MAX_NAME_LEN);
00478 initReiWithDataObjInp (&rei, rsComm, &dataObjInp);
00479 rei.doi = &dataObjInfo;
00480 rei.status = applyRule ("acPostProcForTarFileReg", NULL, &rei,
00481 NO_SAVE_REI);
00482 if (rei.status < 0) {
00483 rodsLogError (LOG_ERROR, rei.status,
00484 "regSubFile: acPostProcForTarFileReg error for %s. status = %d",
00485 dataObjInfo.objPath);
00486 }
00487 }
00488 return status;
00489 }
00490