00001 /******************************************************************************/ 00002 /* */ 00003 /* X r d P s s . c c */ 00004 /* */ 00005 /* (c) 2007 by the Board of Trustees of the Leland Stanford, Jr., University */ 00006 /* All Rights Reserved. See XrdInfo.cc for complete License Terms */ 00007 /* Produced by Andrew Hanushevsky for Stanford University under contract */ 00008 /* DE-AC03-76-SFO0515 with the Deprtment of Energy */ 00009 /******************************************************************************/ 00010 00011 /******************************************************************************/ 00012 /* I n c l u d e s */ 00013 /******************************************************************************/ 00014 00015 #include <unistd.h> 00016 #include <errno.h> 00017 #include <fcntl.h> 00018 #include <signal.h> 00019 #include <strings.h> 00020 #include <stdio.h> 00021 #include <sys/file.h> 00022 #include <sys/stat.h> 00023 #include <sys/types.h> 00024 #ifdef __solaris__ 00025 #include <sys/vnode.h> 00026 #endif 00027 00028 #include "XrdVersion.hh" 00029 00030 #include "XrdFfs/XrdFfsPosix.hh" 00031 #include "XrdPss/XrdPss.hh" 00032 #include "XrdPosix/XrdPosixXrootd.hh" 00033 00034 #include "XrdOss/XrdOssError.hh" 00035 #include "XrdOuc/XrdOucEnv.hh" 00036 #include "XrdSec/XrdSecEntity.hh" 00037 #include "XrdSys/XrdSysError.hh" 00038 #include "XrdSys/XrdSysHeaders.hh" 00039 #include "XrdSys/XrdSysPlatform.hh" 00040 00041 /******************************************************************************/ 00042 /* G l o b a l s */ 00043 /******************************************************************************/ 00044 00045 namespace XrdProxy 00046 { 00047 static XrdPssSys XrdProxySS; 00048 00049 XrdSysError eDest(0, "proxy_"); 00050 00051 static const int PBsz = 4096; 00052 } 00053 00054 using namespace XrdProxy; 00055 00056 /******************************************************************************/ 00057 /* XrdOssGetSS (a.k.a. XrdOssGetStorageSystem) */ 00058 /******************************************************************************/ 00059 00060 // This function is called by the OFS layer to retrieve the Storage System 00061 // object. We return our proxy storage system object if configuration succeeded. 00062 // 00063 extern "C" 00064 { 00065 XrdOss *XrdOssGetStorageSystem(XrdOss *native_oss, 00066 XrdSysLogger *Logger, 00067 const char *config_fn, 00068 const char *parms) 00069 { 00070 00071 // Ignore the parms (we accept none for now) and call the init routine 00072 // 00073 return (XrdProxySS.Init(Logger, config_fn) ? 0 : (XrdOss *)&XrdProxySS); 00074 } 00075 } 00076 00077 /******************************************************************************/ 00078 /* o o s s _ S y s M e t h o d s */ 00079 /******************************************************************************/ 00080 /******************************************************************************/ 00081 /* i n i t */ 00082 /******************************************************************************/ 00083 00084 /* 00085 Function: Initialize proxy subsystem 00086 00087 Input: None 00088 00089 Output: Returns zero upon success otherwise (-errno). 00090 */ 00091 int XrdPssSys::Init(XrdSysLogger *lp, const char *configfn) 00092 { 00093 int NoGo; 00094 const char *tmp; 00095 00096 // Do the herald thing 00097 // 00098 eDest.logger(lp); 00099 eDest.Say("Copr. 2007, Stanford University, Pss Version " XrdVSTRING); 00100 00101 // Initialize the subsystems 00102 // 00103 tmp = ((NoGo=Configure(configfn)) ? "failed." : "completed."); 00104 eDest.Say("------ Proxy storage system initialization ", tmp); 00105 00106 // All done. 00107 // 00108 return NoGo; 00109 } 00110 00111 /******************************************************************************/ 00112 /* C h m o d */ 00113 /******************************************************************************/ 00114 /* 00115 Function: Change file mode. 00116 00117 Input: path - Is the fully qualified name of the target file. 00118 mode - The new mode that the file is to have. 00119 00120 Output: Returns XrdOssOK upon success and -errno upon failure. 00121 00122 Notes: This function is currently unsupported. 00123 */ 00124 00125 int XrdPssSys::Chmod(const char *path, mode_t mode) 00126 { 00127 // We currently do not support chmod() 00128 // 00129 return -ENOTSUP; 00130 } 00131 00132 /******************************************************************************/ 00133 /* c r e a t e */ 00134 /******************************************************************************/ 00135 00136 /* 00137 Function: Create a file named `path' with 'file_mode' access mode bits set. 00138 00139 Input: path - The fully qualified name of the file to create. 00140 access_mode - The Posix access mode bits to be assigned to the file. 00141 These bits correspond to the standard Unix permission 00142 bits (e.g., 744 == "rwxr--r--"). 00143 env - Environmental information. 00144 opts - Set as follows: 00145 XRDOSS_mkpath - create dir path if it does not exist. 00146 XRDOSS_new - the file must not already exist. 00147 x00000000 - x are standard open flags (<<8) 00148 00149 Output: Returns XrdOssOK upon success; (-errno) otherwise. 00150 00151 Notes: We always return ENOTSUP as we really want the create options to be 00152 promoted to the subsequent open(). 00153 */ 00154 int XrdPssSys::Create(const char *tident, const char *path, mode_t Mode, 00155 XrdOucEnv &env, int Opts) 00156 { 00157 00158 return -ENOTSUP; 00159 } 00160 00161 /******************************************************************************/ 00162 /* M k d i r */ 00163 /******************************************************************************/ 00164 /* 00165 Function: Create a directory 00166 00167 Input: path - Is the fully qualified name of the new directory. 00168 mode - The new mode that the directory is to have. 00169 mkpath - If true, makes the full path. 00170 00171 Output: Returns XrdOssOK upon success and -errno upon failure. 00172 00173 Notes: Directories are only created in the local disk cache. 00174 Currently, we do not propogate the mkpath option. 00175 */ 00176 00177 int XrdPssSys::Mkdir(const char *path, mode_t mode, int mkpath) 00178 { 00179 char pbuff[PBsz]; 00180 00181 // Convert path to URL 00182 // 00183 if (!P2URL(pbuff, PBsz, path)) return -ENAMETOOLONG; 00184 00185 // Simply return the proxied result here 00186 // 00187 return (XrdPosixXrootd::Mkdir(pbuff, mode) ? -errno : XrdOssOK); 00188 } 00189 00190 /******************************************************************************/ 00191 /* R e m d i r */ 00192 /******************************************************************************/ 00193 00194 /* 00195 Function: Removes the directory 'path' 00196 00197 Input: path - Is the fully qualified name of the directory to remove. 00198 00199 Output: Returns XrdOssOK upon success and -errno upon failure. 00200 */ 00201 int XrdPssSys::Remdir(const char *path, int Opts) 00202 { 00203 const char *Cgi = (Opts & XRDOSS_Online ? "ofs.lcl=1" : ""); 00204 char pbuff[PBsz], *subPath; 00205 int rc; 00206 00207 // Convert path to URL 00208 // 00209 if (!(subPath = P2URL(pbuff, PBsz, path, allRmdir, Cgi, strlen(Cgi)))) 00210 return -ENAMETOOLONG; 00211 00212 // If unlinks are being forwarded, just execute this on a single node. 00213 // Otherwise, make sure it it's not the base dir and execute everywhere. 00214 // 00215 if (!allRm) rc = XrdPosixXrootd::Rmdir(pbuff); 00216 else {if (!(*subPath)) return -EPERM; 00217 rc = XrdFfsPosix_rmdirall(pbuff, subPath, myUid); 00218 } 00219 00220 // Return the result 00221 // 00222 return (rc ? -errno : XrdOssOK); 00223 } 00224 00225 /******************************************************************************/ 00226 /* R e n a m e */ 00227 /******************************************************************************/ 00228 00229 /* 00230 Function: Renames a file with name 'old_name' to 'new_name'. 00231 00232 Input: old_name - Is the fully qualified name of the file to be renamed. 00233 new_name - Is the fully qualified name that the file is to have. 00234 00235 Output: Returns XrdOssOK upon success and -errno upon failure. 00236 */ 00237 int XrdPssSys::Rename(const char *oldname, const char *newname) 00238 { 00239 char oldName[PBsz], *oldSubP, newName[PBsz], *newSubP; 00240 00241 // If we are not forwarding the request, manually execute it everywhere. 00242 // 00243 if (allMv) return (XrdFfsPosix_renameall(urlPlain, oldname, newname, myUid) 00244 ? -errno : XrdOssOK); 00245 00246 // Convert path to URL 00247 // 00248 if (!(oldSubP = P2URL(oldName, PBsz, oldname)) 00249 || !(newSubP = P2URL(newName, PBsz, newname))) return -ENAMETOOLONG; 00250 00251 // Execute the rename and return result 00252 // 00253 return (XrdPosixXrootd::Rename(oldName, newName) ? -errno : XrdOssOK); 00254 } 00255 00256 /******************************************************************************/ 00257 /* s t a t */ 00258 /******************************************************************************/ 00259 00260 /* 00261 Function: Determine if file 'path' actually exists. 00262 00263 Input: path - Is the fully qualified name of the file to be tested. 00264 buff - pointer to a 'stat' structure to hold the attributes 00265 of the file. 00266 Opts - stat() options. 00267 00268 Output: Returns XrdOssOK upon success and -errno upon failure. 00269 00270 Notes: The XRDOSS_resonly flag in Opts is not supported. 00271 */ 00272 00273 int XrdPssSys::Stat(const char *path, struct stat *buff, int Opts) 00274 { 00275 char pbuff[PBsz]; 00276 00277 // Convert path to URL 00278 // 00279 if (!P2URL(pbuff, PBsz, path)) return -ENAMETOOLONG; 00280 00281 // Return proxied stat 00282 // 00283 return (XrdPosixXrootd::Stat(pbuff, buff) ? -errno : XrdOssOK); 00284 } 00285 00286 /******************************************************************************/ 00287 /* T r u n c a t e */ 00288 /******************************************************************************/ 00289 /* 00290 Function: Truncate a file. 00291 00292 Input: path - Is the fully qualified name of the target file. 00293 flen - The new size that the file is to have. 00294 00295 Output: Returns XrdOssOK upon success and -errno upon failure. 00296 */ 00297 00298 int XrdPssSys::Truncate(const char *path, unsigned long long flen) 00299 { 00300 char pbuff[PBsz]; 00301 00302 // Convert path to URL 00303 // 00304 if (!P2URL(pbuff, PBsz, path)) return -ENAMETOOLONG; 00305 00306 // Return proxied truncate. We only do this on a single machine because the 00307 // redirector will forbid the trunc() if multiple copies exist. 00308 // 00309 return (XrdPosixXrootd::Truncate(pbuff, flen) ? -errno : XrdOssOK); 00310 } 00311 00312 /******************************************************************************/ 00313 /* U n l i n k */ 00314 /******************************************************************************/ 00315 00316 /* 00317 Function: Delete a file from the namespace and release it's data storage. 00318 00319 Input: path - Is the fully qualified name of the file to be removed. 00320 00321 Output: Returns XrdOssOK upon success and -errno upon failure. 00322 */ 00323 int XrdPssSys::Unlink(const char *path, int Opts) 00324 { 00325 const char *Cgi = (Opts & XRDOSS_Online ? "ofs.lcl=1" : ""); 00326 char pbuff[PBsz], *subPath; 00327 int rc; 00328 00329 // Convert path to URL 00330 // 00331 if (!(subPath = P2URL(pbuff, PBsz, path, allRm, Cgi, strlen(Cgi)))) 00332 return -ENAMETOOLONG; 00333 00334 // If unlinks are being forwarded, just execute this on a single node. 00335 // Otherwise, make sure it may be a file and execute everywhere. 00336 // 00337 if (!allRm) rc = XrdPosixXrootd::Unlink(pbuff); 00338 else {if (!(*subPath)) return -EISDIR; 00339 rc = XrdFfsPosix_unlinkall(pbuff, subPath, myUid); 00340 } 00341 00342 // Return the result 00343 // 00344 return (rc ? -errno : XrdOssOK); 00345 } 00346 00347 /******************************************************************************/ 00348 /* P s s D i r M e t h o d s */ 00349 /******************************************************************************/ 00350 /******************************************************************************/ 00351 /* o p e n d i r */ 00352 /******************************************************************************/ 00353 00354 /* 00355 Function: Open the directory `path' and prepare for reading. 00356 00357 Input: path - The fully qualified name of the directory to open. 00358 00359 Output: Returns XrdOssOK upon success; (-errno) otherwise. 00360 */ 00361 int XrdPssDir::Opendir(const char *dir_path) 00362 { 00363 char pbuff[PBsz], *subPath; 00364 int theUid = XrdPssSys::T2UID(tident); 00365 00366 // Return an error if this object is already open 00367 // 00368 if (dirVec) return -XRDOSS_E8001; 00369 00370 // Convert path to URL 00371 // 00372 if (!(subPath = XrdPssSys::P2URL(pbuff,PBsz,dir_path))) return -ENAMETOOLONG; 00373 00374 // Return proxied result 00375 // 00376 if ((numEnt = XrdFfsPosix_readdirall(pbuff, "", &dirVec, theUid)) < 0) 00377 {int rc = -errno; 00378 if (dirVec) {free(dirVec); dirVec = 0;} 00379 return rc; 00380 } else curEnt = 0; 00381 00382 return XrdOssOK; 00383 } 00384 00385 /******************************************************************************/ 00386 /* r e a d d i r */ 00387 /******************************************************************************/ 00388 00389 /* 00390 Function: Read the next entry if directory associated with this object. 00391 00392 Input: buff - Is the address of the buffer that is to hold the next 00393 directory name. 00394 blen - Size of the buffer. 00395 00396 Output: Upon success, places the contents of the next directory entry 00397 in buff. When the end of the directory is encountered buff 00398 will be set to the null string. 00399 00400 Upon failure, returns a (-errno). 00401 00402 Warning: The caller must provide proper serialization. 00403 */ 00404 int XrdPssDir::Readdir(char *buff, int blen) 00405 { 00406 00407 // Check if this object is actually open 00408 // 00409 if (!dirVec) return -XRDOSS_E8002; 00410 00411 // Return a single entry 00412 // 00413 if (curEnt >= numEnt) *buff = 0; 00414 else {strlcpy(buff, dirVec[curEnt], blen); 00415 free(dirVec[curEnt]); 00416 curEnt++; 00417 } 00418 return XrdOssOK; 00419 } 00420 00421 /******************************************************************************/ 00422 /* C l o s e */ 00423 /******************************************************************************/ 00424 00425 /* 00426 Function: Close the directory associated with this object. 00427 00428 Input: None. 00429 00430 Output: Returns XrdOssOK upon success and (errno) upon failure. 00431 */ 00432 int XrdPssDir::Close(long long *retsz) 00433 { 00434 int i; 00435 00436 // Make sure this object is open 00437 // 00438 if (!dirVec) return -XRDOSS_E8002; 00439 00440 // Free up remaining storage 00441 // 00442 for (i = curEnt; i < numEnt; i++) free(dirVec[i]); 00443 free(dirVec); 00444 dirVec = 0; 00445 return XrdOssOK; 00446 } 00447 00448 /******************************************************************************/ 00449 /* o o s s _ F i l e M e t h o d s */ 00450 /******************************************************************************/ 00451 /******************************************************************************/ 00452 /* o p e n */ 00453 /******************************************************************************/ 00454 00455 /* 00456 Function: Open the file `path' in the mode indicated by `Mode'. 00457 00458 Input: path - The fully qualified name of the file to open. 00459 Oflag - Standard open flags. 00460 Mode - Create mode (i.e., rwx). 00461 env - Environmental information. 00462 00463 Output: XrdOssOK upon success; -errno otherwise. 00464 */ 00465 int XrdPssFile::Open(const char *path, int Oflag, mode_t Mode, XrdOucEnv &Env) 00466 { 00467 const char *Cgi = ""; 00468 char pbuff[PBsz]; 00469 int CgiLen; 00470 00471 // Return an error if the object is already open 00472 // 00473 if (fd >= 0) return -XRDOSS_E8003; 00474 00475 // Obtain the cgi info 00476 // 00477 Cgi = Env.Env(CgiLen); 00478 00479 // Convert path to URL 00480 // 00481 if (!XrdPssSys::P2URL(pbuff, PBsz, path, 0, Cgi, CgiLen, tident)) 00482 return -ENAMETOOLONG; 00483 00484 // Return the result of this open 00485 // 00486 return (fd = XrdPosixXrootd::Open(pbuff,Oflag,Mode)) < 0 ? -errno : XrdOssOK; 00487 } 00488 00489 /******************************************************************************/ 00490 /* c l o s e */ 00491 /******************************************************************************/ 00492 00493 /* 00494 Function: Close the file associated with this object. 00495 00496 Input: None. 00497 00498 Output: Returns XrdOssOK upon success aud -errno upon failure. 00499 */ 00500 int XrdPssFile::Close(long long *retsz) 00501 { 00502 if (fd < 0) return -XRDOSS_E8004; 00503 if (retsz) *retsz = 0; 00504 return XrdPosixXrootd::Close(fd) ? -errno : XrdOssOK; 00505 } 00506 00507 /******************************************************************************/ 00508 /* r e a d */ 00509 /******************************************************************************/ 00510 00511 /* 00512 Function: Preread `blen' bytes from the associated file. 00513 00514 Input: offset - The absolute 64-bit byte offset at which to read. 00515 blen - The size to preread. 00516 00517 Output: Returns zero read upon success and -errno upon failure. 00518 */ 00519 00520 ssize_t XrdPssFile::Read(off_t offset, size_t blen) 00521 { 00522 if (fd < 0) return (ssize_t)-XRDOSS_E8004; 00523 00524 return 0; // We haven't implemented this yet! 00525 } 00526 00527 00528 /******************************************************************************/ 00529 /* r e a d */ 00530 /******************************************************************************/ 00531 00532 /* 00533 Function: Read `blen' bytes from the associated file, placing in 'buff' 00534 the data and returning the actual number of bytes read. 00535 00536 Input: buff - Address of the buffer in which to place the data. 00537 offset - The absolute 64-bit byte offset at which to read. 00538 blen - The size of the buffer. This is the maximum number 00539 of bytes that will be read. 00540 00541 Output: Returns the number bytes read upon success and -errno upon failure. 00542 */ 00543 00544 ssize_t XrdPssFile::Read(void *buff, off_t offset, size_t blen) 00545 { 00546 ssize_t retval; 00547 00548 if (fd < 0) return (ssize_t)-XRDOSS_E8004; 00549 00550 return (retval = XrdPosixXrootd::Pread(fd, buff, blen, offset)) < 0 00551 ? (ssize_t)-errno : retval; 00552 } 00553 00554 /******************************************************************************/ 00555 /* R e a d R a w */ 00556 /******************************************************************************/ 00557 00558 /* 00559 Function: Read `blen' bytes from the associated file, placing in 'buff' 00560 the data and returning the actual number of bytes read. 00561 00562 Input: buff - Address of the buffer in which to place the data. 00563 offset - The absolute 64-bit byte offset at which to read. 00564 blen - The size of the buffer. This is the maximum number 00565 of bytes that will be read. 00566 00567 Output: Returns the number bytes read upon success and -errno upon failure. 00568 */ 00569 00570 ssize_t XrdPssFile::ReadRaw(void *buff, off_t offset, size_t blen) 00571 { 00572 return Read(buff, offset, blen); 00573 } 00574 00575 /******************************************************************************/ 00576 /* w r i t e */ 00577 /******************************************************************************/ 00578 00579 /* 00580 Function: Write `blen' bytes to the associated file, from 'buff' 00581 and return the actual number of bytes written. 00582 00583 Input: buff - Address of the buffer from which to get the data. 00584 offset - The absolute 64-bit byte offset at which to write. 00585 blen - The number of bytes to write from the buffer. 00586 00587 Output: Returns the number of bytes written upon success and -errno o/w. 00588 */ 00589 00590 ssize_t XrdPssFile::Write(const void *buff, off_t offset, size_t blen) 00591 { 00592 ssize_t retval; 00593 00594 if (fd < 0) return (ssize_t)-XRDOSS_E8004; 00595 00596 return (retval = XrdPosixXrootd::Pwrite(fd, buff, blen, offset)) < 0 00597 ? (ssize_t)-errno : retval; 00598 } 00599 00600 /******************************************************************************/ 00601 /* f s t a t */ 00602 /******************************************************************************/ 00603 00604 /* 00605 Function: Return file status for the associated file. 00606 00607 Input: buff - Pointer to buffer to hold file status. 00608 00609 Output: Returns XrdOssOK upon success and -errno upon failure. 00610 */ 00611 00612 int XrdPssFile::Fstat(struct stat *buff) 00613 { 00614 if (fd < 0) return -XRDOSS_E8004; 00615 00616 return (XrdPosixXrootd::Fstat(fd, buff) ? -errno : XrdOssOK); 00617 } 00618 00619 /******************************************************************************/ 00620 /* f s y n c */ 00621 /******************************************************************************/ 00622 00623 /* 00624 Function: Synchronize associated file. 00625 00626 Input: None. 00627 00628 Output: Returns XrdOssOK upon success and -errno upon failure. 00629 */ 00630 int XrdPssFile::Fsync(void) 00631 { 00632 if (fd < 0) return -XRDOSS_E8004; 00633 00634 return (XrdPosixXrootd::Fsync(fd) ? -errno : XrdOssOK); 00635 } 00636 00637 /******************************************************************************/ 00638 /* f t r u n c a t e */ 00639 /******************************************************************************/ 00640 00641 /* 00642 Function: Set the length of associated file to 'flen'. 00643 00644 Input: flen - The new size of the file. 00645 00646 Output: Returns XrdOssOK upon success and -errno upon failure. 00647 00648 Notes: If 'flen' is smaller than the current size of the file, the file 00649 is made smaller and the data past 'flen' is discarded. If 'flen' 00650 is larger than the current size of the file, a hole is created 00651 (i.e., the file is logically extended by filling the extra bytes 00652 with zeroes). 00653 00654 If compiled w/o large file support, only lower 32 bits are used. 00655 used. 00656 00657 Currently not supported for proxies. 00658 */ 00659 int XrdPssFile::Ftruncate(unsigned long long flen) 00660 { 00661 if (fd < 0) return -XRDOSS_E8004; 00662 00663 return (XrdPosixXrootd::Ftruncate(fd, flen) ? -errno : XrdOssOK); 00664 } 00665 00666 /******************************************************************************/ 00667 /* g e t M m a p */ 00668 /******************************************************************************/ 00669 00670 /* 00671 Function: Indicate whether or not file is memory mapped. 00672 00673 Input: addr - Points to an address which will receive the location 00674 memory where the file is mapped. If the address is 00675 null, true is returned if a mapping exist. 00676 00677 Output: Returns the size of the file if it is memory mapped (see above). 00678 Otherwise, zero is returned and addr is set to zero. 00679 */ 00680 off_t XrdPssFile::getMmap(void **addr) // Not Supported for proxies 00681 { 00682 if (addr) *addr = 0; 00683 return 0; 00684 } 00685 00686 /******************************************************************************/ 00687 /* i s C o m p r e s s e d */ 00688 /******************************************************************************/ 00689 00690 /* 00691 Function: Indicate whether or not file is compressed. 00692 00693 Input: cxidp - Points to a four byte buffer to hold the compression 00694 algorithm used if the file is compressed or null. 00695 00696 Output: Returns the region size which is 0 if the file is not compressed. 00697 If cxidp is not null, the algorithm is returned only if the file 00698 is compressed. 00699 */ 00700 int XrdPssFile::isCompressed(char *cxidp) // Not supported for proxies 00701 { 00702 return 0; 00703 } 00704 00705 /******************************************************************************/ 00706 /* P 2 U R L */ 00707 /******************************************************************************/ 00708 00709 char *XrdPssSys::P2URL(char *pbuff, int pblen, const char *path, int Split, 00710 const char *Cgi, int CgiLn, const char *Ident) 00711 { 00712 int pfxLen, pathln = strlen(path); 00713 const char *theID = 0, *subPath; 00714 char idBuff[8], *idP, *retPath; 00715 00716 // If we have an Ident then usethe fd number as the userid. This allows us to 00717 // have one stream per open connection. 00718 // 00719 if (Ident && (Ident = index(Ident, ':'))) 00720 {strncpy(idBuff, Ident+1, 7); idBuff[7] = 0; 00721 if ((idP = index(idBuff, '@'))) {*(idP+1) = 0; theID = idBuff;} 00722 } 00723 00724 // Format the header into the buffer and check if we overflowed. Note that there 00725 // can be a maximum of 8 substitutions, so that's how many we provide. 00726 // 00727 if (theID) pfxLen = snprintf(pbuff,pblen,hdrData,theID,theID,theID,theID, 00728 theID,theID,theID,theID); 00729 else if ((pfxLen = urlPlen) < pblen) strcpy(pbuff, urlPlain); 00730 00731 // Calculate if the rest of the data will actually fit (we overestimate by 1) 00732 // 00733 if ((pfxLen + pathln + CgiLn + 1 + (Split ? 1 : 0)) >= pblen) return 0; 00734 retPath = (pbuff += pfxLen); 00735 00736 // If we need to return a split path, then compute where to split it. Note 00737 // that Split assumes that all redundant slashes have been removed. We do 00738 // not add any cgi information if the split fails. 00739 // 00740 if (Split) 00741 {if ((subPath = rindex(path+1, '/')) && *(subPath+1)) 00742 {int n = subPath-path; 00743 strncpy(pbuff, path, n); retPath = pbuff+n; *retPath++ = 0; 00744 strcpy(retPath, subPath); 00745 pathln++; 00746 } else { 00747 strcpy(pbuff, path); 00748 return pbuff+pathln; 00749 } 00750 } else strcpy(pbuff, path); 00751 00752 // Add any cgi information 00753 // 00754 if (CgiLn) 00755 {pbuff += pathln; 00756 *pbuff++ = '?'; 00757 strcpy(pbuff, Cgi); 00758 } 00759 00760 return retPath; 00761 } 00762 00763 /******************************************************************************/ 00764 /* T 2 U I D */ 00765 /******************************************************************************/ 00766 00767 int XrdPssSys::T2UID(const char *Ident) 00768 { 00769 char *Eol; 00770 00771 // We will use the FD number as the userid. If we fail, use ours 00772 // 00773 if (Ident && (Ident = index(Ident, ':'))) 00774 {int theUid = strtol(Ident+1, &Eol, 10); 00775 if (*Eol == '@') return theUid; 00776 } 00777 return myUid; 00778 }