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 addKeyVal( &dataObjInp.condInput, FORCE_FLAG_KW, "" );
00171 l1descInx = rsDataObjCreate (rsComm, &dataObjInp);
00172
00173 }
00174
00175
00176
00177 if( l1descInx < 0 ) {
00178 rodsLog( LOG_ERROR,"rsStructFileBundle: rsDataObjCreate of %s error. status = %d",
00179 dataObjInp.objPath, l1descInx );
00180 return l1descInx;
00181 }
00182
00183
00184
00185 clearKeyVal (&dataObjInp.condInput);
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 chkObjPermAndStat_t chkObjPermAndStatInp;
00200 memset( &chkObjPermAndStatInp, 0, sizeof (chkObjPermAndStatInp));
00201 rstrcpy( chkObjPermAndStatInp.objPath, structFileBundleInp->collection, MAX_NAME_LEN);
00202 chkObjPermAndStatInp.flags = CHK_COLL_FOR_BUNDLE_OPR;
00203 addKeyVal( &chkObjPermAndStatInp.condInput, RESC_NAME_KW, L1desc[l1descInx].dataObjInfo->rescName );
00204
00205
00206
00207 std::string resc_hier;
00208 char* resc_hier_ptr = getValByKey( &structFileBundleInp->condInput, RESC_HIER_STR_KW );
00209 if( !resc_hier_ptr ) {
00210 rodsLog( LOG_NOTICE, "_rsStructFileBundle :: RESC_HIER_STR_KW is NULL" );
00211 } else {
00212 rodsLog( LOG_NOTICE, "_rsStructFileBundle :: RESC_HIER_STR_KW is [%s]", resc_hier_ptr );
00213 addKeyVal( &chkObjPermAndStatInp.condInput, RESC_HIER_STR_KW, resc_hier_ptr );
00214 resc_hier = resc_hier_ptr;
00215 }
00216
00217 status = rsChkObjPermAndStat( rsComm, &chkObjPermAndStatInp );
00218 if( status < 0 ) {
00219 rodsLog( LOG_ERROR,"rsStructFileBundle: rsChkObjPermAndStat of %s error. stat = %d",
00220 chkObjPermAndStatInp.objPath, status );
00221 dataObjCloseInp.l1descInx = l1descInx;
00222 rsDataObjClose( rsComm, &dataObjCloseInp );
00223 return status;
00224 }
00225
00226 clearKeyVal( &chkObjPermAndStatInp.condInput );
00227
00228
00229
00230 createPhyBundleDir( rsComm, L1desc[ l1descInx ].dataObjInfo->filePath, phyBunDir );
00231
00232
00233
00234 collInp_t collInp;
00235 bzero( &collInp, sizeof( collInp ) );
00236 collInp.flags = RECUR_QUERY_FG | VERY_LONG_METADATA_FG | NO_TRIM_REPL_FG | INCLUDE_CONDINPUT_IN_QUERY;
00237 rstrcpy( collInp.collName, structFileBundleInp->collection, MAX_NAME_LEN );
00238 addKeyVal( &collInp.condInput, RESC_NAME_KW, L1desc[ l1descInx ].dataObjInfo->rescName );
00239
00240 rodsLog( LOG_NOTICE, "rsStructFileBundle: calling rsOpenCollection for [%s]", structFileBundleInp->collection );
00241
00242
00243
00244 handleInx = rsOpenCollection( rsComm, &collInp );
00245 if( handleInx < 0 ) {
00246 rodsLog( LOG_ERROR, "rsStructFileBundle: rsOpenCollection of %s error. status = %d",
00247 collInp.collName, handleInx );
00248 rmdir( phyBunDir );
00249 return handleInx;
00250 }
00251
00252
00253
00254 int collLen = 0;
00255 if( ( structFileBundleInp->oprType & PRESERVE_COLL_PATH ) != 0 ) {
00256
00257
00258 char* tmpPtr = collInp.collName;
00259 int tmpLen = 0;
00260 collLen = 0;
00261
00262
00263
00264 while( *tmpPtr != '\0' ) {
00265 if( *tmpPtr == '/' ) {
00266 collLen = tmpLen;
00267 }
00268
00269 tmpLen++;
00270 tmpPtr++;
00271 }
00272
00273 } else {
00274 collLen = strlen( collInp.collName );
00275
00276 }
00277
00278
00279
00280 collEnt_t* collEnt = NULL;
00281 while( ( status = rsReadCollection (rsComm, &handleInx, &collEnt ) ) >= 0 ) {
00282 if( NULL == collEnt ) {
00283 rodsLog( LOG_ERROR, "rsStructFileBundle: collEnt is NULL" );
00284 continue;
00285 }
00286
00287
00288
00289 if (collEnt->objType == DATA_OBJ_T) {
00290 if (collEnt->collName[collLen] == '\0') {
00291 snprintf( tmpPath, MAX_NAME_LEN, "%s/%s", phyBunDir, collEnt->dataName );
00292
00293 } else {
00294 snprintf( tmpPath, MAX_NAME_LEN, "%s/%s/%s", phyBunDir, collEnt->collName + collLen + 1, collEnt->dataName );
00295 mkDirForFilePath( rsComm, phyBunDir, tmpPath, getDefDirMode() );
00296
00297 }
00298
00299
00300
00301 if( resc_hier == collEnt->resc_hier ) {
00302
00303
00304 status = link( collEnt->phyPath, tmpPath );
00305 if( status < 0 ) {
00306 rodsLog( LOG_ERROR, "rsStructFileBundle: link error %s to %s. errno = %d",
00307 collEnt->phyPath, tmpPath, errno );
00308 rmLinkedFilesInUnixDir( phyBunDir );
00309 rmdir( phyBunDir );
00310 return ( UNIX_FILE_LINK_ERR - errno );
00311 } else {
00312
00313 }
00314 } else {
00315
00316 }
00317 } else {
00318
00319
00320 if ((int) strlen (collEnt->collName) + 1 <= collLen) {
00321 free (collEnt);
00322 continue;
00323 }
00324 snprintf (tmpPath, MAX_NAME_LEN, "%s/%s",phyBunDir, collEnt->collName + collLen);
00325 mkdirR (phyBunDir, tmpPath, getDefDirMode ());
00326 }
00327
00328 if( collEnt != NULL ) {
00329 free( collEnt );
00330 collEnt = NULL;
00331 }
00332
00333 }
00334
00335
00336
00337 clearKeyVal( &collInp.condInput );
00338 rsCloseCollection( rsComm, &handleInx );
00339
00340
00341
00342 status = phyBundle( rsComm, L1desc[l1descInx].dataObjInfo, phyBunDir,
00343 collInp.collName, structFileBundleInp->oprType );
00344
00345 int savedStatus = 0;
00346 if (status < 0) {
00347 rodsLog( LOG_ERROR, "rsStructFileBundle: phyBundle of %s error. stat = %d",
00348 L1desc[ l1descInx ].dataObjInfo->objPath, status );
00349 L1desc[ l1descInx ].bytesWritten = 0;
00350 savedStatus = status;
00351 } else {
00352
00353 L1desc[ l1descInx ].bytesWritten = 1;
00354 }
00355
00356
00357
00358 rmLinkedFilesInUnixDir( phyBunDir );
00359 rmdir( phyBunDir );
00360
00361 dataObjCloseInp.l1descInx = l1descInx;
00362 status = rsDataObjClose( rsComm, &dataObjCloseInp );
00363 if( status >= 0 ) {
00364 return savedStatus;
00365 }
00366
00367 return (status);
00368 }
00369
00370 int
00371 remoteStructFileBundle (rsComm_t *rsComm,
00372 structFileExtAndRegInp_t *structFileBundleInp, rodsServerHost_t *rodsServerHost)
00373 {
00374 int status;
00375
00376 if (rodsServerHost == NULL) {
00377 rodsLog (LOG_NOTICE,
00378 "remoteStructFileBundle: Invalid rodsServerHost");
00379 return SYS_INVALID_SERVER_HOST;
00380 }
00381
00382 if ((status = svrToSvrConnect (rsComm, rodsServerHost)) < 0) {
00383 return status;
00384 }
00385
00386 status = rcStructFileBundle (rodsServerHost->conn, structFileBundleInp);
00387 return status;
00388 }
00389