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