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