00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "fileOpr.h"
00010 #include "fileStat.h"
00011 #include "rsGlobalExtern.h"
00012 #include "rcGlobalExtern.h"
00013
00014
00015
00016 #include "eirods_log.h"
00017 #include "eirods_file_object.h"
00018 #include "eirods_collection_object.h"
00019 #include "eirods_stacktrace.h"
00020 #include "eirods_resource_backport.h"
00021 #include "eirods_resource_manager.h"
00022
00023 int
00024 initFileDesc ()
00025 {
00026 memset (FileDesc, 0, sizeof (fileDesc_t) * NUM_FILE_DESC);
00027 return (0);
00028 }
00029
00030 int
00031 allocFileDesc ()
00032 {
00033 int i;
00034
00035 for (i = 3; i < NUM_FILE_DESC; i++) {
00036 if (FileDesc[i].inuseFlag == FD_FREE) {
00037 FileDesc[i].inuseFlag = FD_INUSE;
00038 return (i);
00039 };
00040 }
00041
00042 rodsLog (LOG_NOTICE,
00043 "allocFileDesc: out of FileDesc");
00044
00045 return (SYS_OUT_OF_FILE_DESC);
00046 }
00047
00048 int
00049 allocAndFillFileDesc (rodsServerHost_t *rodsServerHost, char* objPath, char *fileName,
00050 char* rescHier, fileDriverType_t fileType, int fd, int mode)
00051 {
00052 int fileInx;
00053
00054 fileInx = allocFileDesc ();
00055 if (fileInx < 0) {
00056 return (fileInx);
00057 }
00058
00059 FileDesc[fileInx].rodsServerHost = rodsServerHost;
00060 FileDesc[fileInx].objPath = strdup (objPath);
00061 FileDesc[fileInx].fileName = strdup (fileName);
00062 FileDesc[fileInx].rescHier = strdup (rescHier);
00063 FileDesc[fileInx].fileType = fileType;
00064 FileDesc[fileInx].mode = mode;
00065 FileDesc[fileInx].fd = fd;
00066
00067 return (fileInx);
00068 }
00069
00070 int
00071 freeFileDesc (int fileInx)
00072 {
00073 if (fileInx < 3 || fileInx >= NUM_FILE_DESC) {
00074 rodsLog (LOG_NOTICE,
00075 "freeFileDesc: fileInx %d out of range", fileInx);
00076 return (SYS_FILE_DESC_OUT_OF_RANGE);
00077 }
00078
00079 if (FileDesc[fileInx].fileName != NULL) {
00080 free (FileDesc[fileInx].fileName);
00081 }
00082
00083 if(FileDesc[fileInx].rescHier != NULL) {
00084 free (FileDesc[fileInx].rescHier);
00085 }
00086
00087
00088
00089 memset (&FileDesc[fileInx], 0, sizeof (fileDesc_t));
00090
00091 return (0);
00092 }
00093
00094 int
00095 getServerHostByFileInx (int fileInx, rodsServerHost_t **rodsServerHost)
00096 {
00097 int remoteFlag;
00098
00099 if (fileInx < 3 || fileInx >= NUM_FILE_DESC) {
00100 rodsLog (LOG_NOTICE,
00101 "getServerHostByFileInx: Bad fileInx value %d", fileInx);
00102 return (SYS_BAD_FILE_DESCRIPTOR);
00103 }
00104
00105 if (FileDesc[fileInx].inuseFlag == 0) {
00106 rodsLog (LOG_NOTICE,
00107 "getServerHostByFileInx: fileInx %d not active", fileInx);
00108 return (SYS_BAD_FILE_DESCRIPTOR);
00109 }
00110
00111 *rodsServerHost = FileDesc[fileInx].rodsServerHost;
00112 remoteFlag = (*rodsServerHost)->localFlag;
00113
00114 return (remoteFlag);
00115 }
00116
00117 int
00118 mkDirForFilePath (
00119 rsComm_t *rsComm,
00120 const char *startDir,
00121 const char *filePath,
00122 int mode)
00123 {
00124 int status;
00125
00126 char myDir[MAX_NAME_LEN], myFile[MAX_NAME_LEN];
00127
00128 if ((status = splitPathByKey (filePath, myDir, myFile, '/')) < 0) {
00129 rodsLog (LOG_NOTICE,
00130 "mkDirForFilePath: splitPathByKey for %s error, status = %d",
00131 filePath, status);
00132 return (status);
00133 }
00134
00135 status = mkFileDirR (rsComm, startDir, myDir, mode);
00136
00137 return (status);
00138 }
00139
00140
00141
00142 int mkFileDirR(
00143 rsComm_t *rsComm,
00144 const char *startDir,
00145 const char *destDir,
00146 int mode ) {
00147
00148 int startLen;
00149 int pathLen, tmpLen;
00150 char tmpPath[MAX_NAME_LEN];
00151 struct stat statbuf;
00152
00153 startLen = strlen (startDir);
00154 pathLen = strlen (destDir);
00155
00156 rstrcpy (tmpPath, destDir, MAX_NAME_LEN);
00157
00158 tmpLen = pathLen;
00159
00160 while (tmpLen > startLen) {
00161 eirods::collection_object_ptr tmp_coll_obj( new eirods::collection_object( tmpPath, eirods::EIRODS_LOCAL_USE_ONLY_RESOURCE, 0, 0 ) );
00162 eirods::error stat_err = fileStat( rsComm, tmp_coll_obj, &statbuf );
00163 if ( stat_err.code() >= 0) {
00164 if (statbuf.st_mode & S_IFDIR) {
00165 break;
00166 } else {
00167 rodsLog (LOG_NOTICE,
00168 "mkFileDirR: A local non-directory %s already exists \n",
00169 tmpPath);
00170 return (stat_err.code() );
00171 }
00172 } else {
00173
00174 }
00175
00176
00177 while (tmpLen && tmpPath[tmpLen] != '/')
00178 tmpLen --;
00179
00180 tmpPath[tmpLen] = '\0';
00181
00182 }
00183
00184
00185
00186 while (tmpLen < pathLen) {
00187
00188 tmpPath[tmpLen] = '/';
00189
00190 eirods::collection_object_ptr tmp_coll_obj( new eirods::collection_object( tmpPath, eirods::EIRODS_LOCAL_USE_ONLY_RESOURCE, mode, 0 ) );
00191 eirods::error mkdir_err = fileMkdir( rsComm, tmp_coll_obj );
00192 if ( !mkdir_err.ok() && (getErrno ( mkdir_err.code()) != EEXIST)) {
00193 std::stringstream msg;
00194 msg << "fileMkdir for [";
00195 msg << tmpPath;
00196 msg << "]";
00197 eirods::error ret_err = PASSMSG( msg.str(), mkdir_err );
00198 eirods::log( ret_err );
00199
00200 return mkdir_err.code();
00201 }
00202 while (tmpPath[tmpLen] != '\0')
00203 tmpLen ++;
00204 }
00205 return 0;
00206 }
00207
00208
00209
00210 int chkEmptyDir (int fileType, rsComm_t *rsComm, char *cacheDir) {
00211
00212 int status;
00213 char childPath[MAX_NAME_LEN];
00214 struct stat myFileStat;
00215 struct rodsDirent* myFileDirent = 0;
00216
00217
00218
00219 eirods::collection_object_ptr cacheDir_obj( new eirods::collection_object( cacheDir, eirods::EIRODS_LOCAL_USE_ONLY_RESOURCE, 0, 0 ) );
00220 eirods::error opendir_err = fileOpendir( rsComm, cacheDir_obj );
00221
00222
00223
00224
00225 if( !opendir_err.ok() ) {
00226 return 0;
00227 }
00228
00229
00230
00231 eirods::error readdir_err = fileReaddir( rsComm, cacheDir_obj, &myFileDirent );
00232 while( readdir_err.ok() && 0 == readdir_err.code() ) {
00233
00234
00235 if( strcmp( myFileDirent->d_name, "." ) == 0 ||
00236 strcmp( myFileDirent->d_name, "..") == 0) {
00237 readdir_err = fileReaddir( rsComm, cacheDir_obj, &myFileDirent );
00238 continue;
00239 }
00240
00241
00242
00243 snprintf( childPath, MAX_NAME_LEN, "%s/%s", cacheDir, myFileDirent->d_name );
00244 eirods::collection_object_ptr tmp_coll_obj( new eirods::collection_object( childPath, eirods::EIRODS_LOCAL_USE_ONLY_RESOURCE, 0, 0 ) );
00245 eirods::error stat_err = fileStat( rsComm, tmp_coll_obj, &myFileStat );
00246
00247
00248
00249 if( stat_err.code() < 0 ) {
00250 rodsLog( LOG_ERROR, "chkEmptyDir: fileStat error for %s, status = %d",
00251 childPath, status);
00252 break;
00253 }
00254
00255
00256
00257 if( myFileStat.st_mode & S_IFREG ) {
00258 rodsLog( LOG_ERROR, "chkEmptyDir: file %s exists",
00259 childPath, status);
00260 status = SYS_DIR_IN_VAULT_NOT_EMPTY;
00261 break;
00262 }
00263
00264
00265
00266 if (myFileStat.st_mode & S_IFDIR) {
00267 status = chkEmptyDir( -1, rsComm, childPath);
00268 if (status == SYS_DIR_IN_VAULT_NOT_EMPTY) {
00269 rodsLog( LOG_ERROR, "chkEmptyDir: dir %s is not empty", childPath );
00270 break;
00271 }
00272 }
00273
00274
00275
00276 readdir_err = fileReaddir( rsComm, cacheDir_obj, &myFileDirent );
00277
00278 }
00279
00280
00281
00282 eirods::error closedir_err = fileClosedir( rsComm, cacheDir_obj );
00283 if( !closedir_err.ok() ) {
00284 std::stringstream msg;
00285 msg << "fileClosedir failed for [";
00286 msg << cacheDir;
00287 msg << "]";
00288 eirods::error log_err = PASSMSG( msg.str(), closedir_err );
00289 eirods::log( log_err );
00290 }
00291
00292 if( status != SYS_DIR_IN_VAULT_NOT_EMPTY ) {
00293 eirods::collection_object_ptr coll_obj( new eirods::collection_object( cacheDir, eirods::EIRODS_LOCAL_USE_ONLY_RESOURCE, 0, 0 ) );
00294 eirods::error rmdir_err = fileRmdir( rsComm, coll_obj );
00295 if( !rmdir_err.ok() ) {
00296 std::stringstream msg;
00297 msg << "fileRmdir failed for [";
00298 msg << cacheDir;
00299 msg << "]";
00300 eirods::error err = PASSMSG( msg.str(), rmdir_err );
00301 eirods::log ( err );
00302 }
00303 status = 0;
00304 }
00305
00306 return status;
00307
00308 }
00309
00310
00311
00312
00313 int
00314 chkFilePathPerm (rsComm_t *rsComm, fileOpenInp_t *fileOpenInp,
00315 rodsServerHost_t *rodsServerHost, int chkType)
00316 {
00317 int status;
00318
00319 if (chkType == NO_CHK_PATH_PERM) {
00320 return 0;
00321 } else if (chkType == DISALLOW_PATH_REG) {
00322 return PATH_REG_NOT_ALLOWED;
00323 }
00324
00325
00326 status = isValidFilePath (fileOpenInp->fileName);
00327 if (status < 0) return status;
00328
00329
00330 if (rodsServerHost == NULL) {
00331 rodsLog (LOG_NOTICE,
00332 "chkFilePathPerm: NULL rodsServerHost");
00333 return (SYS_INTERNAL_NULL_INPUT_ERR);
00334 }
00335
00336
00337
00338 if (chkType == CHK_NON_VAULT_PATH_PERM) {
00339 status = matchCliVaultPath (rsComm, fileOpenInp->fileName, rodsServerHost);
00340
00341 if (status == 1) {
00342
00343 return (status);
00344 } else if (status == -1) {
00345
00346 return CANT_REG_IN_VAULT_FILE;
00347 }
00348 } else if (chkType == DO_CHK_PATH_PERM) {
00349 std::string out_path;
00350 eirods::error ret = resc_mgr.validate_vault_path( fileOpenInp->fileName, rodsServerHost, out_path );
00351 if( ret.ok() ) {
00352
00353 return CANT_REG_IN_VAULT_FILE;
00354 }
00355 } else {
00356 return SYS_INVALID_INPUT_PARAM;
00357
00358 }
00359
00360 status = rsChkNVPathPermByHost (rsComm, fileOpenInp, rodsServerHost);
00361
00362 return (status);
00363 }
00364
00365
00366
00367
00368
00369
00370 int
00371 isValidFilePath (char *path)
00372 {
00373 char *tmpPtr = NULL;
00374 char *tmpPath = path;
00375 #if 0
00376 if (strstr (path, "/../") != NULL) {
00377
00378 rodsLog (LOG_ERROR,
00379 "isValidFilePath: input fileName %s contains /../", path);
00380 return SYS_INVALID_FILE_PATH;
00381 }
00382 #endif
00383 while ((tmpPtr = strstr (tmpPath, "/..")) != NULL) {
00384 if (tmpPtr[3] == '\0' || tmpPtr[3] == '/') {
00385
00386 rodsLog (LOG_ERROR,"isValidFilePath: inp fileName %s contains /../ or ends with /..",path);
00387 return SYS_INVALID_FILE_PATH;
00388 } else {
00389 tmpPath += 3;
00390 }
00391 }
00392 return 0;
00393 }
00394
00395
00396
00397
00398
00399
00400 int matchCliVaultPath(
00401 rsComm_t* _comm,
00402 const std::string& _path,
00403 rodsServerHost_t* _svr_host ) {
00404
00405
00406 if( !_comm ) {
00407 rodsLog( LOG_ERROR, "matchCliVaultPath :: null comm" );
00408 return SYS_INVALID_INPUT_PARAM;
00409 }
00410
00411 if( _path.empty() ) {
00412 rodsLog( LOG_ERROR, "matchCliVaultPath :: empty file path" );
00413 return SYS_INVALID_INPUT_PARAM;
00414 }
00415
00416 if( !_svr_host ) {
00417 rodsLog( LOG_ERROR, "matchCliVaultPath :: null server host" );
00418 return SYS_INVALID_INPUT_PARAM;
00419 }
00420
00421
00422
00423 std::string vault_path;
00424 eirods::error ret = resc_mgr.validate_vault_path( _path, _svr_host, vault_path );
00425 if( !ret.ok() || vault_path.empty() ) {
00426 return 0;
00427 }
00428
00429
00430
00431 std::string user_path = _path.substr( vault_path.size() );
00432
00433
00434
00435 const size_t home_pos = ( user_path[0] == '/' ) ? 1 : 0;
00436
00437
00438
00439 size_t pos = user_path.find( "home/" );
00440 if( home_pos != pos ) {
00441 rodsLog( LOG_NOTICE, "matchCliVaultPath :: home/ is not found in the proper location for path [%s]",
00442 user_path.c_str() );
00443 return -1;
00444 }
00445
00446
00447
00448 const size_t user_pos = home_pos + 5;
00449
00450
00451
00452 pos = user_path.find( _comm->clientUser.userName );
00453 if( user_pos != pos ) {
00454 rodsLog( LOG_NOTICE, "matchCliVaultPath :: [%s] is not found in the proper location for path [%s]",
00455 _comm->clientUser.userName, user_path.c_str() );
00456 return -1;
00457 }
00458
00459
00460
00461 return 1;
00462
00463 #if 0
00464 int len, nameLen;
00465 char *tmpPath;
00466 char *outVaultPath = NULL;
00467
00468
00469 if ((len =
00470 matchVaultPath (rsComm, filePath, rodsServerHost, &outVaultPath)) == 0) {
00471
00472 return (0);
00473 }
00474
00475
00476
00477 nameLen = strlen (rsComm->clientUser.userName);
00478
00479 tmpPath = filePath + len + 1;
00480
00481 if (strncmp (tmpPath, "home/", 5) != 0) return -1;
00482 tmpPath += 5;
00483 if( strncmp (tmpPath, rsComm->clientUser.userName, nameLen) == 0 &&
00484 (tmpPath[nameLen] == '/' || tmpPath[len] == '\0') )
00485 return 1;
00486 else
00487 return 0;
00488
00489 return -1;
00490 #endif
00491 }
00492
00493
00494
00495
00496 int
00497 filePathTypeInResc (
00498 rsComm_t* rsComm,
00499 char* objPath,
00500 char* fileName,
00501 char* rescHier,
00502 rescInfo_t* rescInfo ) {
00503 fileStatInp_t fileStatInp;
00504 rodsStat_t *myStat = NULL;
00505 int status;
00506
00507
00508
00509 std::string location;
00510 eirods::error ret = eirods::get_loc_for_hier_string( rescHier, location );
00511 if( !ret.ok() ) {
00512 eirods::log( PASSMSG( "failed in get_loc_for_hier_string", ret ) );
00513 return -1;
00514 }
00515
00516 memset (&fileStatInp, 0, sizeof (fileStatInp));
00517 rstrcpy (fileStatInp.fileName, fileName, MAX_NAME_LEN);
00518 rstrcpy (fileStatInp.rescHier, rescHier, MAX_NAME_LEN);
00519 rstrcpy (fileStatInp.objPath, objPath, MAX_NAME_LEN);
00520 fileStatInp.fileType = static_cast< fileDriverType_t >( -1 );
00521 rstrcpy (fileStatInp.addr.hostAddr, location.c_str(), NAME_LEN);
00522 status = rsFileStat (rsComm, &fileStatInp, &myStat);
00523
00524 if (status < 0 || NULL == myStat ) return status;
00525 if (myStat->st_mode & S_IFREG) {
00526 free (myStat);
00527 return LOCAL_FILE_T;
00528 } else if (myStat->st_mode & S_IFDIR) {
00529 free (myStat);
00530 return LOCAL_DIR_T;
00531 } else {
00532 free (myStat);
00533 return UNKNOWN_OBJ_T;
00534 }
00535 }
00536
00537 int
00538 bindStreamToIRods (rodsServerHost_t *rodsServerHost, int fd)
00539 {
00540 int fileInx;
00541
00542 fileInx = allocAndFillFileDesc (rodsServerHost, "", STREAM_FILE_NAME, "",
00543 UNIX_FILE_TYPE, fd, DEFAULT_FILE_MODE);
00544
00545 return fileInx;
00546 }
00547