00001
00002
00003
00004
00005
00006
00007
00008 #include "apiHeaderAll.h"
00009 #include "objMetaOpr.h"
00010 #include "dataObjOpr.h"
00011 #include "physPath.h"
00012 #include "miscServerFunct.h"
00013 #include "rcGlobalExtern.h"
00014 #include "reGlobalsExtern.h"
00015
00016
00017
00018 #include "eirods_log.h"
00019 #include "eirods_file_object.h"
00020 #include "eirods_stacktrace.h"
00021 #include "eirods_resource_redirect.h"
00022
00023 int
00024 rsStructFileBundle (rsComm_t *rsComm,
00025 structFileExtAndRegInp_t *structFileBundleInp)
00026 {
00027 #if 0
00028 char *destRescName = NULL;
00029 #endif
00030 int status;
00031 rodsServerHost_t *rodsServerHost;
00032 int remoteFlag;
00033
00034 dataObjInp_t dataObjInp;
00035
00036
00037 memset (&dataObjInp, 0, sizeof (dataObjInp));
00038 rstrcpy (dataObjInp.objPath, structFileBundleInp->objPath,
00039 MAX_NAME_LEN);
00040
00041 remoteFlag = getAndConnRemoteZone (rsComm, &dataObjInp, &rodsServerHost,
00042 REMOTE_CREATE);
00043
00044 if (remoteFlag < 0) {
00045 return (remoteFlag);
00046 } else if (remoteFlag == REMOTE_HOST) {
00047 status = rcStructFileBundle (rodsServerHost->conn,
00048 structFileBundleInp);
00049 return status;
00050 }
00051
00052 #if 0
00053 if ((destRescName =
00054 getValByKey (&structFileBundleInp->condInput, DEST_RESC_NAME_KW)) == NULL
00055 && (destRescName =
00056 getValByKey (&structFileBundleInp->condInput, DEF_RESC_NAME_KW)) == NULL) {
00057 return USER_NO_RESC_INPUT_ERR;
00058 }
00059
00060 status = _getRescInfo (rsComm, destRescName, &rescGrpInfo);
00061 if (status < 0) {
00062 rodsLog (LOG_ERROR,
00063 "rsStructFileBundle: _getRescInfo of %s error for %s. stat = %d",
00064 destRescName, structFileBundleInp->collection, status);
00065 return status;
00066 }
00067 #else
00068
00069
00070
00071
00072 #endif
00073 #if 0
00074 bzero (&rescAddr, sizeof (rescAddr));
00075
00076 remoteFlag = resolveHost (&rescAddr, &rodsServerHost);
00077
00078 if (remoteFlag == LOCAL_HOST) {
00079 status = _rsStructFileBundle (rsComm, structFileBundleInp);
00080 } else if (remoteFlag == REMOTE_HOST) {
00081 status = remoteStructFileBundle (rsComm, structFileBundleInp,
00082 rodsServerHost);
00083 } else if (remoteFlag < 0) {
00084 status = remoteFlag;
00085 }
00086 freeAllRescGrpInfo (rescGrpInfo);
00087 #endif
00088
00089
00090
00091
00092 std::string hier;
00093 int local = LOCAL_HOST;
00094 rodsServerHost_t* host = 0;
00095 dataObjInp_t data_inp;
00096 bzero( &data_inp, sizeof( data_inp ) );
00097 rstrcpy( data_inp.objPath, structFileBundleInp->objPath, MAX_NAME_LEN );
00098 copyKeyValPairStruct( &structFileBundleInp->condInput, &data_inp.condInput );
00099 if( getValByKey( &structFileBundleInp->condInput, RESC_HIER_STR_KW ) == NULL ) {
00100 eirods::error ret = eirods::resource_redirect( eirods::EIRODS_CREATE_OPERATION, rsComm,
00101 &data_inp, hier, host, local );
00102 if( !ret.ok() ) {
00103 std::stringstream msg;
00104 msg << "rsStructFileBundle :: failed in eirods::resource_redirect for [";
00105 msg << &data_inp.objPath << "]";
00106 eirods::log( PASSMSG( msg.str(), ret ) );
00107 return ret.code();
00108 }
00109
00110
00111
00112
00113 addKeyVal( &structFileBundleInp->condInput, RESC_HIER_STR_KW, hier.c_str() );
00114
00115 }
00116
00117 if( LOCAL_HOST == local ) {
00118 status = _rsStructFileBundle( rsComm, structFileBundleInp );
00119 } else {
00120 status = rcStructFileBundle( host->conn, structFileBundleInp );
00121 }
00122
00123
00124 return status;
00125 }
00126
00127 int _rsStructFileBundle( rsComm_t* rsComm,
00128 structFileExtAndRegInp_t* structFileBundleInp ) {
00129 int status;
00130 int handleInx;
00131 char phyBunDir[MAX_NAME_LEN];
00132 char tmpPath[MAX_NAME_LEN];
00133 int l1descInx;
00134 char* dataType = 0;
00135 openedDataObjInp_t dataObjCloseInp;
00136
00137
00138
00139 dataObjInp_t dataObjInp;
00140 memset (&dataObjInp, 0, sizeof (dataObjInp));
00141 dataObjInp.openFlags = O_WRONLY;
00142
00143
00144
00145 dataType = getValByKey( &structFileBundleInp->condInput, DATA_TYPE_KW );
00146
00147
00148
00149 if( dataType != NULL && strstr( dataType, ZIP_DT_STR ) != NULL ) {
00150 int len = strlen (structFileBundleInp->objPath);
00151 if (strcmp (&structFileBundleInp->objPath[len - 4], ".zip") != 0) {
00152 strcat (structFileBundleInp->objPath, ".zip");
00153 }
00154 }
00155
00156
00157
00158 rstrcpy( dataObjInp.objPath, structFileBundleInp->objPath, MAX_NAME_LEN );
00159
00160
00161
00162 replKeyVal( &structFileBundleInp->condInput, &dataObjInp.condInput );
00163
00164
00165
00166 if( ( structFileBundleInp->oprType & ADD_TO_TAR_OPR ) != 0 ) {
00167 l1descInx = rsDataObjOpen( rsComm, &dataObjInp );
00168
00169 } else {
00170 l1descInx = rsDataObjCreate (rsComm, &dataObjInp);
00171
00172 }
00173
00174
00175
00176 if( l1descInx < 0 ) {
00177 rodsLog( LOG_ERROR,"rsStructFileBundle: rsDataObjCreate of %s error. status = %d",
00178 dataObjInp.objPath, l1descInx );
00179 return l1descInx;
00180 }
00181
00182
00183
00184 clearKeyVal (&dataObjInp.condInput);
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 chkObjPermAndStat_t chkObjPermAndStatInp;
00199 memset( &chkObjPermAndStatInp, 0, sizeof (chkObjPermAndStatInp));
00200 rstrcpy( chkObjPermAndStatInp.objPath, structFileBundleInp->collection, MAX_NAME_LEN);
00201 chkObjPermAndStatInp.flags = CHK_COLL_FOR_BUNDLE_OPR;
00202 addKeyVal( &chkObjPermAndStatInp.condInput, RESC_NAME_KW, L1desc[l1descInx].dataObjInfo->rescName );
00203
00204
00205
00206 std::string resc_hier;
00207 char* resc_hier_ptr = getValByKey( &structFileBundleInp->condInput, RESC_HIER_STR_KW );
00208 if( !resc_hier_ptr ) {
00209 rodsLog( LOG_NOTICE, "_rsStructFileBundle :: RESC_HIER_STR_KW is NULL" );
00210 } else {
00211 addKeyVal( &chkObjPermAndStatInp.condInput, RESC_HIER_STR_KW, resc_hier_ptr );
00212 resc_hier = resc_hier_ptr;
00213 }
00214
00215 status = rsChkObjPermAndStat( rsComm, &chkObjPermAndStatInp );
00216 if( status < 0 ) {
00217 rodsLog( LOG_ERROR,"rsStructFileBundle: rsChkObjPermAndStat of %s error. stat = %d",
00218 chkObjPermAndStatInp.objPath, status );
00219 dataObjCloseInp.l1descInx = l1descInx;
00220 rsDataObjClose( rsComm, &dataObjCloseInp );
00221 return status;
00222 }
00223
00224 clearKeyVal( &chkObjPermAndStatInp.condInput );
00225
00226
00227
00228 createPhyBundleDir( rsComm, L1desc[ l1descInx ].dataObjInfo->filePath, phyBunDir );
00229
00230
00231
00232 collInp_t collInp;
00233 bzero( &collInp, sizeof( collInp ) );
00234 collInp.flags = RECUR_QUERY_FG | VERY_LONG_METADATA_FG | NO_TRIM_REPL_FG | INCLUDE_CONDINPUT_IN_QUERY;
00235 rstrcpy( collInp.collName, structFileBundleInp->collection, MAX_NAME_LEN );
00236 addKeyVal( &collInp.condInput, RESC_NAME_KW, L1desc[ l1descInx ].dataObjInfo->rescName );
00237
00238 rodsLog( LOG_NOTICE, "rsStructFileBundle: calling rsOpenCollection for [%s]", structFileBundleInp->collection );
00239
00240
00241
00242 handleInx = rsOpenCollection( rsComm, &collInp );
00243 if( handleInx < 0 ) {
00244 rodsLog( LOG_ERROR, "rsStructFileBundle: rsOpenCollection of %s error. status = %d",
00245 collInp.collName, handleInx );
00246 rmdir( phyBunDir );
00247 return handleInx;
00248 }
00249
00250
00251
00252 int collLen = 0;
00253 if( ( structFileBundleInp->oprType & PRESERVE_COLL_PATH ) != 0 ) {
00254
00255
00256 char* tmpPtr = collInp.collName;
00257 int tmpLen = 0;
00258 collLen = 0;
00259
00260
00261
00262 while( *tmpPtr != '\0' ) {
00263 if( *tmpPtr == '/' ) {
00264 collLen = tmpLen;
00265 }
00266
00267 tmpLen++;
00268 tmpPtr++;
00269 }
00270
00271 } else {
00272 collLen = strlen( collInp.collName );
00273
00274 }
00275
00276
00277
00278 collEnt_t* collEnt = NULL;
00279 while( ( status = rsReadCollection (rsComm, &handleInx, &collEnt ) ) >= 0 ) {
00280 if( NULL == collEnt ) {
00281 rodsLog( LOG_ERROR, "rsStructFileBundle: collEnt is NULL" );
00282 continue;
00283 }
00284
00285
00286
00287 if (collEnt->objType == DATA_OBJ_T) {
00288 if (collEnt->collName[collLen] == '\0') {
00289 snprintf( tmpPath, MAX_NAME_LEN, "%s/%s", phyBunDir, collEnt->dataName );
00290
00291 } else {
00292 snprintf( tmpPath, MAX_NAME_LEN, "%s/%s/%s", phyBunDir, collEnt->collName + collLen + 1, collEnt->dataName );
00293 mkDirForFilePath( rsComm, phyBunDir, tmpPath, getDefDirMode() );
00294
00295 }
00296
00297
00298
00299 if( resc_hier == collEnt->resc_hier ) {
00300
00301
00302 status = link( collEnt->phyPath, tmpPath );
00303 if( status < 0 ) {
00304 rodsLog( LOG_ERROR, "rsStructFileBundle: link error %s to %s. errno = %d",
00305 collEnt->phyPath, tmpPath, errno );
00306 rmLinkedFilesInUnixDir( phyBunDir );
00307 rmdir( phyBunDir );
00308 return ( UNIX_FILE_LINK_ERR - errno );
00309 } else {
00310
00311 }
00312 } else {
00313
00314 }
00315 } else {
00316
00317
00318 if ((int) strlen (collEnt->collName) + 1 <= collLen) {
00319 free (collEnt);
00320 continue;
00321 }
00322 snprintf (tmpPath, MAX_NAME_LEN, "%s/%s",phyBunDir, collEnt->collName + collLen);
00323 mkdirR (phyBunDir, tmpPath, getDefDirMode ());
00324 }
00325
00326 if( collEnt != NULL ) {
00327 free( collEnt );
00328 collEnt = NULL;
00329 }
00330
00331 }
00332
00333
00334
00335 clearKeyVal( &collInp.condInput );
00336 rsCloseCollection( rsComm, &handleInx );
00337
00338
00339
00340 status = phyBundle( rsComm, L1desc[l1descInx].dataObjInfo, phyBunDir,
00341 collInp.collName, structFileBundleInp->oprType );
00342
00343 int savedStatus = 0;
00344 if (status < 0) {
00345 rodsLog( LOG_ERROR, "rsStructFileBundle: phyBundle of %s error. stat = %d",
00346 L1desc[ l1descInx ].dataObjInfo->objPath, status );
00347 L1desc[ l1descInx ].bytesWritten = 0;
00348 savedStatus = status;
00349 } else {
00350
00351 L1desc[ l1descInx ].bytesWritten = 1;
00352 }
00353
00354
00355
00356 rmLinkedFilesInUnixDir( phyBunDir );
00357 rmdir( phyBunDir );
00358
00359 dataObjCloseInp.l1descInx = l1descInx;
00360 status = rsDataObjClose( rsComm, &dataObjCloseInp );
00361 if( status >= 0 ) {
00362 return savedStatus;
00363 }
00364
00365 return (status);
00366 }
00367
00368 int
00369 remoteStructFileBundle (rsComm_t *rsComm,
00370 structFileExtAndRegInp_t *structFileBundleInp, rodsServerHost_t *rodsServerHost)
00371 {
00372 int status;
00373
00374 if (rodsServerHost == NULL) {
00375 rodsLog (LOG_NOTICE,
00376 "remoteStructFileBundle: Invalid rodsServerHost");
00377 return SYS_INVALID_SERVER_HOST;
00378 }
00379
00380 if ((status = svrToSvrConnect (rsComm, rodsServerHost)) < 0) {
00381 return status;
00382 }
00383
00384 status = rcStructFileBundle (rodsServerHost->conn, structFileBundleInp);
00385 return status;
00386 }
00387