00001
00002
00003
00004
00005
00006
00007 #include "fileOpr.h"
00008 #include "fileStat.h"
00009 #include "rsGlobalExtern.h"
00010 #include "rcGlobalExtern.h"
00011
00012 int
00013 initFileDesc ()
00014 {
00015 memset (FileDesc, 0, sizeof (fileDesc_t) * NUM_FILE_DESC);
00016 return (0);
00017 }
00018
00019 int
00020 allocFileDesc ()
00021 {
00022 int i;
00023
00024 for (i = 3; i < NUM_FILE_DESC; i++) {
00025 if (FileDesc[i].inuseFlag == FD_FREE) {
00026 FileDesc[i].inuseFlag = FD_INUSE;
00027 return (i);
00028 };
00029 }
00030
00031 rodsLog (LOG_NOTICE,
00032 "allocFileDesc: out of FileDesc");
00033
00034 return (SYS_OUT_OF_FILE_DESC);
00035 }
00036
00037 int
00038 allocAndFillFileDesc (rodsServerHost_t *rodsServerHost, char *fileName,
00039 fileDriverType_t fileType, int fd, int mode)
00040 {
00041 int fileInx;
00042
00043 fileInx = allocFileDesc ();
00044 if (fileInx < 0) {
00045 return (fileInx);
00046 }
00047
00048 FileDesc[fileInx].rodsServerHost = rodsServerHost;
00049 FileDesc[fileInx].fileName = strdup (fileName);
00050 FileDesc[fileInx].fileType = fileType;
00051 FileDesc[fileInx].mode = mode;
00052 FileDesc[fileInx].fd = fd;
00053
00054 return (fileInx);
00055 }
00056
00057 int
00058 freeFileDesc (int fileInx)
00059 {
00060 if (fileInx < 3 || fileInx >= NUM_FILE_DESC) {
00061 rodsLog (LOG_NOTICE,
00062 "freeFileDesc: fileInx %d out of range", fileInx);
00063 return (SYS_FILE_DESC_OUT_OF_RANGE);
00064 }
00065
00066 if (FileDesc[fileInx].fileName != NULL) {
00067 free (FileDesc[fileInx].fileName);
00068 }
00069
00070
00071
00072 memset (&FileDesc[fileInx], 0, sizeof (fileDesc_t));
00073
00074 return (0);
00075 }
00076
00077 int
00078 getServerHostByFileInx (int fileInx, rodsServerHost_t **rodsServerHost)
00079 {
00080 int remoteFlag;
00081
00082 if (fileInx < 3 || fileInx >= NUM_FILE_DESC) {
00083 rodsLog (LOG_NOTICE,
00084 "getServerHostByFileInx: Bad fileInx value %d", fileInx);
00085 return (SYS_BAD_FILE_DESCRIPTOR);
00086 }
00087
00088 if (FileDesc[fileInx].inuseFlag == 0) {
00089 rodsLog (LOG_NOTICE,
00090 "getServerHostByFileInx: fileInx %d not active", fileInx);
00091 return (SYS_BAD_FILE_DESCRIPTOR);
00092 }
00093
00094 *rodsServerHost = FileDesc[fileInx].rodsServerHost;
00095 remoteFlag = (*rodsServerHost)->localFlag;
00096
00097 return (remoteFlag);
00098 }
00099
00100 int
00101 mkDirForFilePath (int fileType, rsComm_t *rsComm, char *startDir,
00102 char *filePath, int mode)
00103 {
00104 int status;
00105
00106 char myDir[MAX_NAME_LEN], myFile[MAX_NAME_LEN];
00107
00108 if ((status = splitPathByKey (filePath, myDir, myFile, '/')) < 0) {
00109 rodsLog (LOG_NOTICE,
00110 "mkDirForFilePath: splitPathByKey for %s error, status = %d",
00111 filePath, status);
00112 return (status);
00113 }
00114
00115 status = mkFileDirR (fileType, rsComm, startDir, myDir, mode);
00116
00117 return (status);
00118 }
00119
00120
00121
00122 int
00123 mkFileDirR (int fileType, rsComm_t *rsComm, char *startDir,
00124 char *destDir, int mode)
00125 {
00126 int status;
00127 int startLen;
00128 int pathLen, tmpLen;
00129 char tmpPath[MAX_NAME_LEN];
00130 struct stat statbuf;
00131
00132 startLen = strlen (startDir);
00133 pathLen = strlen (destDir);
00134
00135 rstrcpy (tmpPath, destDir, MAX_NAME_LEN);
00136
00137 tmpLen = pathLen;
00138
00139 while (tmpLen > startLen) {
00140 status = fileStat ( (fileDriverType_t)fileType, rsComm, tmpPath, &statbuf);
00141 if (status >= 0) {
00142 if (statbuf.st_mode & S_IFDIR) {
00143 break;
00144 } else {
00145 rodsLog (LOG_NOTICE,
00146 "mkFileDirR: A local non-directory %s already exists \n",
00147 tmpPath);
00148 return (status);
00149 }
00150 }
00151
00152
00153
00154 while (tmpLen && tmpPath[tmpLen] != '/')
00155 tmpLen --;
00156 tmpPath[tmpLen] = '\0';
00157 }
00158
00159
00160 while (tmpLen < pathLen) {
00161
00162 tmpPath[tmpLen] = '/';
00163 status = fileMkdir ((fileDriverType_t)fileType, rsComm, tmpPath, mode);
00164 if (status < 0 && (getErrno (status) != EEXIST)) {
00165 rodsLog (LOG_NOTICE,
00166 "mkFileDirR: mkdir failed for %s, status =%d",
00167 tmpPath, status);
00168 return status;
00169 }
00170 #if 0
00171 while (tmpLen && tmpPath[tmpLen] != '\0')
00172 #endif
00173 while (tmpPath[tmpLen] != '\0')
00174 tmpLen ++;
00175 }
00176 return 0;
00177 }
00178
00179 int
00180 chkEmptyDir (int fileType, rsComm_t *rsComm, char *cacheDir)
00181 {
00182 void *dirPtr = NULL;
00183 #if defined(solaris_platform)
00184 char fileDirent[sizeof (struct dirent) + MAX_NAME_LEN];
00185 struct dirent *myFileDirent = (struct dirent *) fileDirent;
00186 #else
00187 struct dirent fileDirent;
00188 struct dirent *myFileDirent = &fileDirent;
00189 #endif
00190 int status;
00191 char childPath[MAX_NAME_LEN];
00192 struct stat myFileStat;
00193
00194 status = fileOpendir ((fileDriverType_t)fileType, rsComm, cacheDir, &dirPtr);
00195
00196 if (status < 0) {
00197 return (0);
00198 }
00199
00200 while ((status = fileReaddir ((fileDriverType_t)fileType, rsComm, dirPtr, myFileDirent))
00201 >= 0) {
00202 if (strcmp (myFileDirent->d_name, ".") == 0 ||
00203 strcmp (myFileDirent->d_name, "..") == 0) {
00204 continue;
00205 }
00206 snprintf (childPath, MAX_NAME_LEN, "%s/%s", cacheDir,
00207 myFileDirent->d_name);
00208
00209 status = fileStat ((fileDriverType_t)fileType, rsComm, childPath, &myFileStat);
00210
00211 if (status < 0) {
00212 rodsLog (LOG_ERROR,
00213 "chkEmptyDir: fileStat error for %s, status = %d",
00214 childPath, status);
00215 break;
00216 }
00217 if (myFileStat.st_mode & S_IFREG) {
00218 rodsLog (LOG_ERROR,
00219 "chkEmptyDir: file %s exists",
00220 childPath, status);
00221 status = SYS_DIR_IN_VAULT_NOT_EMPTY;
00222 break;
00223 }
00224
00225 if (myFileStat.st_mode & S_IFDIR) {
00226 status = chkEmptyDir ((fileDriverType_t)fileType, rsComm, childPath);
00227 if (status == SYS_DIR_IN_VAULT_NOT_EMPTY) {
00228 rodsLog (LOG_ERROR,
00229 "chkEmptyDir: dir %s is not empty", childPath);
00230 break;
00231 }
00232 }
00233 }
00234 fileClosedir ((fileDriverType_t)fileType, rsComm, dirPtr);
00235 if (status != SYS_DIR_IN_VAULT_NOT_EMPTY) {
00236 fileRmdir ((fileDriverType_t)fileType, rsComm, cacheDir);
00237 status = 0;
00238 }
00239 return status;
00240 }
00241
00242
00243
00244
00245 int
00246 chkFilePathPerm (rsComm_t *rsComm, fileOpenInp_t *fileOpenInp,
00247 rodsServerHost_t *rodsServerHost, int chkType)
00248 {
00249 int status;
00250
00251
00252 char *outVaultPath = NULL;
00253
00254 if (chkType == NO_CHK_PATH_PERM) {
00255 return 0;
00256 } else if (chkType == DISALLOW_PATH_REG) {
00257 return PATH_REG_NOT_ALLOWED;
00258 }
00259
00260
00261 status = isValidFilePath (fileOpenInp->fileName);
00262 if (status < 0) return status;
00263
00264
00265 if (rodsServerHost == NULL) {
00266 rodsLog (LOG_NOTICE,
00267 "chkFilePathPerm: NULL rodsServerHost");
00268 return (SYS_INTERNAL_NULL_INPUT_ERR);
00269 }
00270
00271
00272
00273 if (chkType == CHK_NON_VAULT_PATH_PERM) {
00274 rodsLog( LOG_NOTICE, "XXXX - chkType == CHK_NON_VAULT_PATH_PERM" );
00275 status = matchCliVaultPath (rsComm, fileOpenInp->fileName, rodsServerHost);
00276
00277 rodsLog( LOG_NOTICE, "XXXX - status: %d", status );
00278
00279 if (status == 1) {
00280
00281 return (status);
00282 } else if (status == -1) {
00283
00284 return CANT_REG_IN_VAULT_FILE;
00285 }
00286 } else if (chkType == DO_CHK_PATH_PERM) {
00287 rodsLog( LOG_NOTICE, "XXXX - chkType == DO_CHK_PATH_PERM" );
00288 int ret = matchVaultPath (rsComm, fileOpenInp->fileName, rodsServerHost, &outVaultPath );
00289 rodsLog( LOG_NOTICE, "XXXX - ret:%d ", ret );
00290 if( ret > 0 ) {
00291
00292
00293 return CANT_REG_IN_VAULT_FILE;
00294 }
00295 } else {
00296 return SYS_INVALID_INPUT_PARAM;
00297
00298 }
00299
00300 rodsLog( LOG_NOTICE, "XXXX - rsChkNVPathPermByHost" );
00301 status = rsChkNVPathPermByHost (rsComm, fileOpenInp, rodsServerHost);
00302
00303 return (status);
00304 }
00305
00306
00307
00308
00309
00310
00311 int
00312 isValidFilePath (char *path)
00313 {
00314 char *tmpPtr = NULL;
00315 char *tmpPath = path;
00316 #if 0
00317 if (strstr (path, "/../") != NULL) {
00318
00319 rodsLog (LOG_ERROR,
00320 "isValidFilePath: input fileName %s contains /../", path);
00321 return SYS_INVALID_FILE_PATH;
00322 }
00323 #endif
00324 while ((tmpPtr = strstr (tmpPath, "/..")) != NULL) {
00325 if (tmpPtr[3] == '\0' || tmpPtr[3] == '/') {
00326
00327 rodsLog (LOG_ERROR,"isValidFilePath: inp fileName %s contains /../ or ends with /..",path);
00328 return SYS_INVALID_FILE_PATH;
00329 } else {
00330 tmpPath += 3;
00331 }
00332 }
00333 return 0;
00334 }
00335
00336 int
00337 matchVaultPath (rsComm_t *rsComm, char *filePath,
00338 rodsServerHost_t *rodsServerHost, char **outVaultPath)
00339 {
00340 rescGrpInfo_t *tmpRescGrpInfo;
00341 rescInfo_t *tmpRescInfo;
00342 int len;
00343 rodsLog( LOG_NOTICE, "YYYY - filePath: %s", filePath );
00344 if (isValidFilePath (filePath) < 0) {
00345
00346 rodsLog( LOG_NOTICE, "YYYY - invalid filePath: %s", filePath );
00347 return (0);
00348 }
00349 tmpRescGrpInfo = RescGrpInfo;
00350
00351 while (tmpRescGrpInfo != NULL) {
00352 tmpRescInfo = tmpRescGrpInfo->rescInfo;
00353
00354 if (tmpRescInfo->rodsServerHost == rodsServerHost) {
00355 rodsLog( LOG_NOTICE, "YYYY - filePath: %s vs tmpRescInfo->rescVaultPath: %s", filePath, tmpRescInfo->rescVaultPath );
00356 len = strlen (tmpRescInfo->rescVaultPath);
00357 rodsLog( LOG_NOTICE, "YYYY - len: %d", len );
00358 rodsLog( LOG_NOTICE, "YYYY - strncmp: %d", strncmp ( tmpRescInfo->rescVaultPath, filePath, len ) );
00359 rodsLog( LOG_NOTICE, "YYYY - filePath[len]: %c", filePath[len] );
00360 if( strncmp ( tmpRescInfo->rescVaultPath, filePath, len ) == 0 &&
00361 ( filePath[len] == '/' || filePath[len] == '\0' ) ) {
00362 rodsLog( LOG_NOTICE, "YYYY - match outVaultPath: %s", tmpRescInfo->rescVaultPath );
00363 *outVaultPath = tmpRescInfo->rescVaultPath;
00364 return (len);
00365 }
00366 }
00367 tmpRescGrpInfo = tmpRescGrpInfo->next;
00368 }
00369
00370
00371 return (0);
00372 }
00373
00374
00375
00376
00377
00378
00379 int
00380 matchCliVaultPath (rsComm_t *rsComm, char *filePath,
00381 rodsServerHost_t *rodsServerHost)
00382 {
00383 int len, nameLen;
00384 char *tmpPath;
00385 char *outVaultPath = NULL;
00386
00387
00388 if ((len =
00389 matchVaultPath (rsComm, filePath, rodsServerHost, &outVaultPath)) == 0) {
00390
00391 return (0);
00392 }
00393
00394
00395
00396 nameLen = strlen (rsComm->clientUser.userName);
00397
00398 tmpPath = filePath + len + 1;
00399
00400 if (strncmp (tmpPath, "home/", 5) != -1) return -1;
00401 tmpPath += 5;
00402 if( strncmp (tmpPath, rsComm->clientUser.userName, nameLen) == 0 &&
00403 (tmpPath[nameLen] == '/' || tmpPath[len] == '\0') )
00404 return 1;
00405 else
00406 return 0;
00407
00408 return -1;
00409 }
00410
00411
00412
00413
00414 int
00415 filePathTypeInResc (rsComm_t *rsComm, char *fileName, rescInfo_t *rescInfo)
00416 {
00417 int rescTypeInx;
00418 fileStatInp_t fileStatInp;
00419 rodsStat_t *myStat = NULL;
00420 int status;
00421
00422 memset (&fileStatInp, 0, sizeof (fileStatInp));
00423
00424 rstrcpy (fileStatInp.fileName, fileName, MAX_NAME_LEN);
00425
00426 rescTypeInx = rescInfo->rescTypeInx;
00427 fileStatInp.fileType = (fileDriverType_t)RescTypeDef[rescTypeInx].driverType;
00428 rstrcpy (fileStatInp.addr.hostAddr, rescInfo->rescLoc, NAME_LEN);
00429 status = rsFileStat (rsComm, &fileStatInp, &myStat);
00430
00431 if (status < 0 || NULL == myStat ) return status;
00432 if (myStat->st_mode & S_IFREG) {
00433 free (myStat);
00434 return LOCAL_FILE_T;
00435 } else if (myStat->st_mode & S_IFDIR) {
00436 free (myStat);
00437 return LOCAL_DIR_T;
00438 } else {
00439 free (myStat);
00440 return UNKNOWN_OBJ_T;
00441 }
00442 }
00443
00444 int
00445 bindStreamToIRods (rodsServerHost_t *rodsServerHost, int fd)
00446 {
00447 int fileInx;
00448
00449 fileInx = allocAndFillFileDesc (rodsServerHost, STREAM_FILE_NAME,
00450 UNIX_FILE_TYPE, fd, DEFAULT_FILE_MODE);
00451
00452 return fileInx;
00453 }
00454