XrdSfsNative.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                       X r d X f s N a t i v e . c c                        */
00004 /*                                                                            */
00005 /* (c) 2004 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 //          $Id: XrdSfsNative.cc 35287 2010-09-14 21:19:35Z ganis $
00012 
00013 const char *XrdSfsNativeCVSID = "$Id: XrdSfsNative.cc 35287 2010-09-14 21:19:35Z ganis $";
00014 
00015 #include <sys/types.h>
00016 #include <unistd.h>
00017 #include <dirent.h>
00018 #include <errno.h>
00019 #include <fcntl.h>
00020 #include <memory.h>
00021 #include <string.h>
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <sys/param.h>
00025 #include <sys/stat.h>
00026 
00027 #include "XrdVersion.hh"
00028 #include "XrdSys/XrdSysError.hh"
00029 #include "XrdSys/XrdSysHeaders.hh"
00030 #include "XrdSys/XrdSysLogger.hh"
00031 #include "XrdSys/XrdSysPthread.hh"
00032 #include "XrdSec/XrdSecInterface.hh"
00033 #include "XrdSfs/XrdSfsAio.hh"
00034 #include "XrdSfs/XrdSfsNative.hh"
00035 
00036 #ifdef AIX
00037 #include <sys/mode.h>
00038 #endif
00039 
00040 /******************************************************************************/
00041 /*       O S   D i r e c t o r y   H a n d l i n g   I n t e r f a c e        */
00042 /******************************************************************************/
00043 
00044 #ifndef S_IAMB
00045 #define S_IAMB  0x1FF
00046 #endif
00047 
00048 /******************************************************************************/
00049 /*                        G l o b a l   O b j e c t s                         */
00050 /******************************************************************************/
00051   
00052 XrdSysError    *XrdSfsNative::eDest;
00053 
00054 /******************************************************************************/
00055 /*            U n i x   F i l e   S y s t e m   I n t e r f a c e             */
00056 /******************************************************************************/
00057 
00058 class XrdSfsUFS
00059 {
00060 public:
00061 
00062 static int Chmod(const char *fn, mode_t mode) {return chmod(fn, mode);}
00063 
00064 static int Close(int fd) {return close(fd);}
00065 
00066 static int Mkdir(const char *fn, mode_t mode) {return mkdir(fn, mode);}
00067 
00068 static int Open(const char *path, int oflag, mode_t omode)
00069                {return open(path, oflag, omode);}
00070 
00071 static int Rem(const char *fn) {return unlink(fn);}
00072 
00073 static int Remdir(const char *fn) {return rmdir(fn);}
00074 
00075 static int Rename(const char *ofn, const char *nfn) {return rename(ofn, nfn);}
00076 
00077 static int Statfd(int fd, struct stat *buf) {return  fstat(fd, buf);}
00078 
00079 static int Statfn(const char *fn, struct stat *buf) {return stat(fn, buf);}
00080 
00081 static int Truncate(const char *fn, off_t flen) {return truncate(fn, flen);}
00082 };
00083   
00084 /******************************************************************************/
00085 /*                           C o n s t r u c t o r                            */
00086 /******************************************************************************/
00087 
00088 XrdSfsNative::XrdSfsNative(XrdSysError *ep)
00089 {
00090   eDest = ep;
00091 }
00092   
00093 /******************************************************************************/
00094 /*                         G e t F i l e S y s t e m                          */
00095 /******************************************************************************/
00096   
00097 XrdSfsFileSystem *XrdSfsGetFileSystem(XrdSfsFileSystem *native_fs, 
00098                                       XrdSysLogger     *lp)
00099 {
00100  static XrdSysError  Eroute(lp, "XrdSfs");
00101  static XrdSfsNative myFS(&Eroute);
00102 
00103  Eroute.Say("Copr.  2007 Stanford University/SLAC "
00104                "sfs (Standard File System) v 9.0n");
00105 
00106  return &myFS;
00107 }
00108 
00109 /******************************************************************************/
00110 /*           D i r e c t o r y   O b j e c t   I n t e r f a c e s            */
00111 /******************************************************************************/
00112 /******************************************************************************/
00113 /*                                  o p e n                                   */
00114 /******************************************************************************/
00115   
00116 int XrdSfsNativeDirectory::open(const char              *dir_path, // In
00117                                 const XrdSecClientName  *client,   // In
00118                                 const char              *info)     // In
00119 /*
00120   Function: Open the directory `path' and prepare for reading.
00121 
00122   Input:    path      - The fully qualified name of the directory to open.
00123             cred      - Authentication credentials, if any.
00124             info      - Opaque information, if any.
00125 
00126   Output:   Returns SFS_OK upon success, otherwise SFS_ERROR.
00127 */
00128 {
00129    static const char *epname = "opendir";
00130 
00131 // Verify that this object is not already associated with an open directory
00132 //
00133      if (dh) return
00134         XrdSfsNative::Emsg(epname, error, EADDRINUSE, 
00135                              "open directory", dir_path);
00136 
00137 // Set up values for this directory object
00138 //
00139    ateof = 0;
00140    fname = strdup(dir_path);
00141 
00142 // Open the directory and get it's id
00143 //
00144      if (!(dh = opendir(dir_path))) return
00145         XrdSfsNative::Emsg(epname,error,errno,"open directory",dir_path);
00146 
00147 // All done
00148 //
00149    return SFS_OK;
00150 }
00151 
00152 /******************************************************************************/
00153 /*                             n e x t E n t r y                              */
00154 /******************************************************************************/
00155 
00156 const char *XrdSfsNativeDirectory::nextEntry()
00157 /*
00158   Function: Read the next directory entry.
00159 
00160   Input:    None.
00161 
00162   Output:   Upon success, returns the contents of the next directory entry as
00163             a null terminated string. Returns a null pointer upon EOF or an
00164             error. To differentiate the two cases, getErrorInfo will return
00165             0 upon EOF and an actual error code (i.e., not 0) on error.
00166 */
00167 {
00168     static const char *epname = "nextEntry";
00169     struct dirent *rp;
00170     int retc;
00171 
00172 // Lock the direcrtory and do any required tracing
00173 //
00174    if (!dh) 
00175       {XrdSfsNative::Emsg(epname,error,EBADF,"read directory",fname);
00176        return (const char *)0;
00177       }
00178 
00179 // Check if we are at EOF (once there we stay there)
00180 //
00181    if (ateof) return (const char *)0;
00182 
00183 // Read the next directory entry
00184 //
00185    errno = 0;
00186    if ((retc = readdir_r(dh, d_pnt, &rp)))
00187       {if (retc && errno != 0)
00188           XrdSfsNative::Emsg(epname,error,retc,"read directory",fname);
00189        d_pnt->d_name[0] = '\0';
00190        return (const char *)0;
00191       }
00192 
00193 // Check if we have reached end of file
00194 //
00195    if (retc || !rp || !d_pnt->d_name[0])
00196       {ateof = 1;
00197        error.clear();
00198        return (const char *)0;
00199       }
00200 
00201 // Return the actual entry
00202 //
00203    return (const char *)(d_pnt->d_name);
00204 }
00205 
00206 /******************************************************************************/
00207 /*                                 c l o s e                                  */
00208 /******************************************************************************/
00209   
00210 int XrdSfsNativeDirectory::close()
00211 /*
00212   Function: Close the directory object.
00213 
00214   Input:    cred       - Authentication credentials, if any.
00215 
00216   Output:   Returns SFS_OK upon success and SFS_ERROR upon failure.
00217 */
00218 {
00219    static const char *epname = "closedir";
00220 
00221 // Release the handle
00222 //
00223     if (dh && closedir(dh))
00224        {XrdSfsNative::Emsg(epname, error, errno, "close directory", fname);
00225         return SFS_ERROR;
00226        }
00227 
00228 // Do some clean-up
00229 //
00230    if (fname) free(fname);
00231    dh = (DIR *)0; 
00232    return SFS_OK;
00233 }
00234 
00235 /******************************************************************************/
00236 /*                F i l e   O b j e c t   I n t e r f a c e s                 */
00237 /******************************************************************************/
00238 /******************************************************************************/
00239 /*                                  o p e n                                   */
00240 /******************************************************************************/
00241 
00242 int XrdSfsNativeFile::open(const char          *path,      // In
00243                            XrdSfsFileOpenMode   open_mode, // In
00244                            mode_t               Mode,      // In
00245                      const XrdSecClientName    *client,    // In
00246                      const char                *info)      // In
00247 /*
00248   Function: Open the file `path' in the mode indicated by `open_mode'.  
00249 
00250   Input:    path      - The fully qualified name of the file to open.
00251             open_mode - One of the following flag values:
00252                         SFS_O_RDONLY - Open file for reading.
00253                         SFS_O_WRONLY - Open file for writing.
00254                         SFS_O_RDWR   - Open file for update
00255                         SFS_O_CREAT  - Create the file open in RDWR mode
00256                         SFS_O_TRUNC  - Trunc  the file open in RDWR mode
00257             Mode      - The Posix access mode bits to be assigned to the file.
00258                         These bits correspond to the standard Unix permission
00259                         bits (e.g., 744 == "rwxr--r--"). Mode may also conatin
00260                         SFS_O_MKPTH is the full path is to be created. The
00261                         agument is ignored unless open_mode = SFS_O_CREAT.
00262             client    - Authentication credentials, if any.
00263             info      - Opaque information to be used as seen fit.
00264 
00265   Output:   Returns OOSS_OK upon success, otherwise SFS_ERROR is returned.
00266 */
00267 {
00268    static const char *epname = "open";
00269    const int AMode = S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH; // 775
00270    char *opname;
00271    mode_t acc_mode = Mode & S_IAMB;
00272    int retc, open_flag = 0;
00273    struct stat buf;
00274 
00275 // Verify that this object is not already associated with an open file
00276 //
00277    if (oh >= 0)
00278       return XrdSfsNative::Emsg(epname,error,EADDRINUSE,"open file",path);
00279    fname = strdup(path);
00280 
00281 // Set the actual open mode
00282 //
00283    switch(open_mode & (SFS_O_RDONLY | SFS_O_WRONLY | SFS_O_RDWR))
00284    {
00285    case SFS_O_RDONLY: open_flag = O_RDONLY; break;
00286    case SFS_O_WRONLY: open_flag = O_WRONLY; break;
00287    case SFS_O_RDWR:   open_flag = O_RDWR;   break;
00288    default:           open_flag = O_RDONLY; break;
00289    }
00290 
00291 // Prepare to create or open the file, as needed
00292 //
00293    if (open_mode & SFS_O_CREAT)
00294       {open_flag  = O_RDWR | O_CREAT | O_EXCL;
00295        opname = (char *)"create";
00296        if ((Mode & SFS_O_MKPTH) && (retc = XrdSfsNative::Mkpath(path,AMode,info)))
00297           return XrdSfsNative::Emsg(epname,error,retc,"create path for",path);
00298       } else if (open_mode & SFS_O_TRUNC)
00299                 {open_flag  = O_RDWR | O_CREAT | O_TRUNC;
00300                  opname = (char *)"truncate";
00301                 } else opname = (char *)"open";
00302 
00303 // Open the file and make sure it is a file
00304 //
00305    if ((oh = XrdSfsUFS::Open(path, open_flag, acc_mode)) >= 0)
00306       {do {retc = XrdSfsUFS::Statfd(oh, &buf);} while(retc && errno == EINTR);
00307        if (!retc && !(buf.st_mode & S_IFREG))
00308           {close(); oh = (buf.st_mode & S_IFDIR ? -EISDIR : -ENOTBLK);}
00309       } else {
00310        oh = -errno;
00311        if (errno == EEXIST)
00312           {do {retc = XrdSfsUFS::Statfn(path, &buf);}
00313               while(retc && errno == EINTR);
00314            if (!retc && (buf.st_mode & S_IFDIR)) oh = -EISDIR;
00315           }
00316       }
00317 
00318 // All done.
00319 //
00320    if (oh < 0) return XrdSfsNative::Emsg(epname, error, oh, opname, path);
00321    return SFS_OK;
00322 }
00323 
00324 /******************************************************************************/
00325 /*                                 c l o s e                                  */
00326 /******************************************************************************/
00327 
00328 int XrdSfsNativeFile::close()
00329 /*
00330   Function: Close the file object.
00331 
00332   Input:    None
00333 
00334   Output:   Returns SFS_OK upon success and SFS_ERROR upon failure.
00335 */
00336 {
00337    static const char *epname = "close";
00338 
00339 // Release the handle and return
00340 //
00341     if (oh >= 0  && XrdSfsUFS::Close(oh))
00342        return XrdSfsNative::Emsg(epname, error, errno, "close", fname);
00343     oh = -1;
00344     if (fname) {free(fname); fname = 0;}
00345     return SFS_OK;
00346 }
00347 
00348 /******************************************************************************/
00349 /*                                  f c t l                                   */
00350 /******************************************************************************/
00351 
00352 int      XrdSfsNativeFile::fctl(const int               cmd,
00353                                 const char             *args,
00354                                       XrdOucErrInfo    &out_error)
00355 {
00356 // See if we can do this
00357 //
00358    if (cmd == SFS_FCTL_GETFD)
00359       {out_error.setErrCode(oh);
00360        return SFS_OK;
00361       }
00362 
00363 // We don't support this
00364 //
00365    out_error.setErrInfo(EEXIST, "fctl operation not supported");
00366    return SFS_ERROR;
00367 }
00368   
00369 /******************************************************************************/
00370 /*                                  r e a d                                   */
00371 /******************************************************************************/
00372 
00373 XrdSfsXferSize XrdSfsNativeFile::read(XrdSfsFileOffset  offset,    // In
00374                                       char             *buff,      // Out
00375                                       XrdSfsXferSize    blen)      // In
00376 /*
00377   Function: Read `blen' bytes at `offset' into 'buff' and return the actual
00378             number of bytes read.
00379 
00380   Input:    offset    - The absolute byte offset at which to start the read.
00381             buff      - Address of the buffer in which to place the data.
00382             blen      - The size of the buffer. This is the maximum number
00383                         of bytes that will be read from 'fd'.
00384 
00385   Output:   Returns the number of bytes read upon success and SFS_ERROR o/w.
00386 */
00387 {
00388    static const char *epname = "read";
00389    XrdSfsXferSize nbytes;
00390 
00391 // Make sure the offset is not too large
00392 //
00393 #if _FILE_OFFSET_BITS!=64
00394    if (offset >  0x000000007fffffff)
00395       return XrdSfsNative::Emsg(epname, error, EFBIG, "read", fname);
00396 #endif
00397 
00398 // Read the actual number of bytes
00399 //
00400    do { nbytes = pread(oh, (void *)buff, (size_t)blen, (off_t)offset); }
00401         while(nbytes < 0 && errno == EINTR);
00402 
00403    if (nbytes  < 0)
00404       return XrdSfsNative::Emsg(epname, error, errno, "read", fname);
00405 
00406 // Return number of bytes read
00407 //
00408    return nbytes;
00409 }
00410   
00411 /******************************************************************************/
00412 /*                              r e a d   A I O                               */
00413 /******************************************************************************/
00414   
00415 int XrdSfsNativeFile::read(XrdSfsAio *aiop)
00416 {
00417 
00418 // Execute this request in a synchronous fashion
00419 //
00420    aiop->Result = this->read((XrdSfsFileOffset)aiop->sfsAio.aio_offset,
00421                                        (char *)aiop->sfsAio.aio_buf,
00422                                (XrdSfsXferSize)aiop->sfsAio.aio_nbytes);
00423    aiop->doneRead();
00424    return 0;
00425 }
00426 
00427 /******************************************************************************/
00428 /*                                 w r i t e                                  */
00429 /******************************************************************************/
00430 
00431 XrdSfsXferSize XrdSfsNativeFile::write(XrdSfsFileOffset   offset,    // In
00432                                        const char        *buff,      // In
00433                                        XrdSfsXferSize     blen)      // In
00434 /*
00435   Function: Write `blen' bytes at `offset' from 'buff' and return the actual
00436             number of bytes written.
00437 
00438   Input:    offset    - The absolute byte offset at which to start the write.
00439             buff      - Address of the buffer from which to get the data.
00440             blen      - The size of the buffer. This is the maximum number
00441                         of bytes that will be written to 'fd'.
00442 
00443   Output:   Returns the number of bytes written upon success and SFS_ERROR o/w.
00444 
00445   Notes:    An error return may be delayed until the next write(), close(), or
00446             sync() call.
00447 */
00448 {
00449    static const char *epname = "write";
00450    XrdSfsXferSize nbytes;
00451 
00452 // Make sure the offset is not too large
00453 //
00454 #if _FILE_OFFSET_BITS!=64
00455    if (offset >  0x000000007fffffff)
00456       return XrdSfsNative::Emsg(epname, error, EFBIG, "write", fname);
00457 #endif
00458 
00459 // Write the requested bytes
00460 //
00461    do { nbytes = pwrite(oh, (void *)buff, (size_t)blen, (off_t)offset); }
00462         while(nbytes < 0 && errno == EINTR);
00463 
00464    if (nbytes  < 0)
00465       return XrdSfsNative::Emsg(epname, error, errno, "write", fname);
00466 
00467 // Return number of bytes written
00468 //
00469    return nbytes;
00470 }
00471 
00472 /******************************************************************************/
00473 /*                             w r i t e   A I O                              */
00474 /******************************************************************************/
00475   
00476 int XrdSfsNativeFile::write(XrdSfsAio *aiop)
00477 {
00478 
00479 // Execute this request in a synchronous fashion
00480 //
00481    aiop->Result = this->write((XrdSfsFileOffset)aiop->sfsAio.aio_offset,
00482                                         (char *)aiop->sfsAio.aio_buf,
00483                                 (XrdSfsXferSize)aiop->sfsAio.aio_nbytes);
00484    aiop->doneWrite();
00485    return 0;
00486 }
00487   
00488 /******************************************************************************/
00489 /*                                  s t a t                                   */
00490 /******************************************************************************/
00491 
00492 int XrdSfsNativeFile::stat(struct stat     *buf)         // Out
00493 /*
00494   Function: Return file status information
00495 
00496   Input:    buf         - The stat structiure to hold the results
00497 
00498   Output:   Returns SFS_OK upon success and SFS_ERROR upon failure.
00499 */
00500 {
00501    static const char *epname = "stat";
00502 
00503 // Execute the function
00504 //
00505    if (XrdSfsUFS::Statfd(oh, buf))
00506       return XrdSfsNative::Emsg(epname, error, errno, "state", fname);
00507 
00508 // All went well
00509 //
00510    return SFS_OK;
00511 }
00512 
00513 /******************************************************************************/
00514 /*                                  s y n c                                   */
00515 /******************************************************************************/
00516 
00517 int XrdSfsNativeFile::sync()
00518 /*
00519   Function: Commit all unwritten bytes to physical media.
00520 
00521   Input:    None
00522 
00523   Output:   Returns SFS_OK upon success and SFS_ERROR upon failure.
00524 */
00525 {
00526    static const char *epname = "sync";
00527 
00528 // Perform the function
00529 //
00530    if (fsync(oh))
00531       return XrdSfsNative::Emsg(epname,error,errno,"synchronize",fname);
00532 
00533 // All done
00534 //
00535    return SFS_OK;
00536 }
00537 
00538 /******************************************************************************/
00539 /*                              s y n c   A I O                               */
00540 /******************************************************************************/
00541   
00542 int XrdSfsNativeFile::sync(XrdSfsAio *aiop)
00543 {
00544 
00545 // Execute this request in a synchronous fashion
00546 //
00547    aiop->Result = this->sync();
00548    aiop->doneWrite();
00549    return 0;
00550 }
00551 
00552 /******************************************************************************/
00553 /*                              t r u n c a t e                               */
00554 /******************************************************************************/
00555 
00556 int XrdSfsNativeFile::truncate(XrdSfsFileOffset  flen)  // In
00557 /*
00558   Function: Set the length of the file object to 'flen' bytes.
00559 
00560   Input:    flen      - The new size of the file.
00561 
00562   Output:   Returns SFS_OK upon success and SFS_ERROR upon failure.
00563 
00564   Notes:    If 'flen' is smaller than the current size of the file, the file
00565             is made smaller and the data past 'flen' is discarded. If 'flen'
00566             is larger than the current size of the file, a hole is created
00567             (i.e., the file is logically extended by filling the extra bytes 
00568             with zeroes).
00569 */
00570 {
00571    static const char *epname = "trunc";
00572 
00573 // Make sure the offset is not too larg
00574 //
00575    if (sizeof(off_t) < sizeof(flen) && flen >  0x000000007fffffff)
00576       return XrdSfsNative::Emsg(epname, error, EFBIG, "truncate", fname);
00577 
00578 // Perform the function
00579 //
00580    if (ftruncate(oh, flen))
00581       return XrdSfsNative::Emsg(epname, error, errno, "truncate", fname);
00582 
00583 // All done
00584 //
00585    return SFS_OK;
00586 }
00587 
00588 /******************************************************************************/
00589 /*         F i l e   S y s t e m   O b j e c t   I n t e r f a c e s          */
00590 /******************************************************************************/
00591 /******************************************************************************/
00592 /*                                 c h m o d                                  */
00593 /******************************************************************************/
00594 
00595 int XrdSfsNative::chmod(const char             *path,    // In
00596                               XrdSfsMode        Mode,    // In
00597                               XrdOucErrInfo    &error,   // Out
00598                         const XrdSecClientName *client,  // In
00599                         const char             *info)    // In
00600 /*
00601   Function: Change the mode on a file or directory.
00602 
00603   Input:    path      - Is the fully qualified name of the file to be removed.
00604             einfo     - Error information object to hold error details.
00605             client    - Authentication credentials, if any.
00606             info      - Opaque information, if any.
00607 
00608   Output:   Returns SFS_OK upon success and SFS_ERROR upon failure.
00609 */
00610 {
00611    static const char *epname = "chmod";
00612    mode_t acc_mode = Mode & S_IAMB;
00613 
00614 // Perform the actual deletion
00615 //
00616    if (XrdSfsUFS::Chmod(path, acc_mode) )
00617       return XrdSfsNative::Emsg(epname,error,errno,"change mode on",path);
00618 
00619 // All done
00620 //
00621     return SFS_OK;
00622 }
00623   
00624 /******************************************************************************/
00625 /*                                e x i s t s                                 */
00626 /******************************************************************************/
00627 
00628 int XrdSfsNative::exists(const char                *path,        // In
00629                                XrdSfsFileExistence &file_exists, // Out
00630                                XrdOucErrInfo       &error,       // Out
00631                          const XrdSecClientName    *client,      // In
00632                          const char                *info)        // In
00633 /*
00634   Function: Determine if file 'path' actually exists.
00635 
00636   Input:    path        - Is the fully qualified name of the file to be tested.
00637             file_exists - Is the address of the variable to hold the status of
00638                           'path' when success is returned. The values may be:
00639                           XrdSfsFileExistsIsDirectory - file not found but path is valid.
00640                           XrdSfsFileExistsIsFile      - file found.
00641                           XrdSfsFileExistsIsNo        - neither file nor directory.
00642             einfo       - Error information object holding the details.
00643             client      - Authentication credentials, if any.
00644             info        - Opaque information, if any.
00645 
00646   Output:   Returns SFS_OK upon success and SFS_ERROR upon failure.
00647 
00648   Notes:    When failure occurs, 'file_exists' is not modified.
00649 */
00650 {
00651    static const char *epname = "exists";
00652    struct stat fstat;
00653 
00654 // Now try to find the file or directory
00655 //
00656    if (!XrdSfsUFS::Statfn(path, &fstat) )
00657       {     if (S_ISDIR(fstat.st_mode)) file_exists=XrdSfsFileExistIsDirectory;
00658        else if (S_ISREG(fstat.st_mode)) file_exists=XrdSfsFileExistIsFile;
00659        else                             file_exists=XrdSfsFileExistNo;
00660        return SFS_OK;
00661       }
00662    if (errno == ENOENT)
00663       {file_exists=XrdSfsFileExistNo;
00664        return SFS_OK;
00665       }
00666 
00667 // An error occured, return the error info
00668 //
00669    return XrdSfsNative::Emsg(epname, error, errno, "locate", path);
00670 }
00671 
00672 /******************************************************************************/
00673 /*                                 f s c t l                                  */
00674 /******************************************************************************/
00675 
00676 int XrdSfsNative::fsctl(const int               cmd,
00677                         const char             *args,
00678                               XrdOucErrInfo    &out_error,
00679                         const XrdSecClientName *client)
00680 {
00681     out_error.setErrInfo(ENOTSUP, "Operation not supported.");
00682     return SFS_ERROR;
00683 }
00684   
00685 /******************************************************************************/
00686 /*                            g e t V e r s i o n                             */
00687 /******************************************************************************/
00688 
00689 const char *XrdSfsNative::getVersion() {return XrdVERSION;}
00690 
00691 /******************************************************************************/
00692 /*                                 m k d i r                                  */
00693 /******************************************************************************/
00694 
00695 int XrdSfsNative::mkdir(const char             *path,    // In
00696                               XrdSfsMode        Mode,    // In
00697                               XrdOucErrInfo    &error,   // Out
00698                         const XrdSecClientName *client,  // In
00699                         const char             *info)    // In
00700 /*
00701   Function: Create a directory entry.
00702 
00703   Input:    path      - Is the fully qualified name of the file to be removed.
00704             Mode      - Is the POSIX mode setting for the directory. If the
00705                         mode contains SFS_O_MKPTH, the full path is created.
00706             einfo     - Error information object to hold error details.
00707             client    - Authentication credentials, if any.
00708             info      - Opaque information, if any.
00709 
00710   Output:   Returns SFS_OK upon success and SFS_ERROR upon failure.
00711 */
00712 {
00713    static const char *epname = "mkdir";
00714    mode_t acc_mode = Mode & S_IAMB;
00715 
00716 // Create the path if it does not already exist
00717 //
00718    if (Mode & SFS_O_MKPTH) Mkpath(path, acc_mode, info);
00719 
00720 // Perform the actual deletion
00721 //
00722    if (XrdSfsUFS::Mkdir(path, acc_mode) )
00723       return XrdSfsNative::Emsg(epname,error,errno,"create directory",path);
00724 
00725 // All done
00726 //
00727     return SFS_OK;
00728 }
00729 
00730 /******************************************************************************/
00731 /*                                M k p a t h                                 */
00732 /******************************************************************************/
00733 /*
00734   Function: Create a directory path
00735 
00736   Input:    path        - Is the fully qualified name of the new path.
00737             mode        - The new mode that each new directory is to have.
00738             info        - Opaque information, of any.
00739 
00740   Output:   Returns 0 upon success and -errno upon failure.
00741 */
00742 
00743 int XrdSfsNative::Mkpath(const char *path, mode_t mode, const char *info)
00744 {
00745     char actual_path[MAXPATHLEN], *local_path, *next_path;
00746     unsigned int plen;
00747     struct stat buf;
00748 
00749 // Extract out the path we should make
00750 //
00751    if (!(plen = strlen(path))) return -ENOENT;
00752    if (plen >= sizeof(actual_path)) return -ENAMETOOLONG;
00753    strcpy(actual_path, path);
00754    if (actual_path[plen-1] == '/') actual_path[plen-1] = '\0';
00755 
00756 // Typically, the path exist. So, do a quick check before launching into it
00757 //
00758    if (!(local_path = rindex(actual_path, (int)'/'))
00759    ||  local_path == actual_path) return 0;
00760    *local_path = '\0';
00761    if (!XrdSfsUFS::Statfn(actual_path, &buf)) return 0;
00762    *local_path = '/';
00763 
00764 // Start creating directories starting with the root. Notice that we will not
00765 // do anything with the last component. The caller is responsible for that.
00766 //
00767    local_path = actual_path+1;
00768    while((next_path = index(local_path, int('/'))))
00769         {*next_path = '\0';
00770          if (XrdSfsUFS::Mkdir(actual_path,mode) && errno != EEXIST)
00771             return -errno;
00772          *next_path = '/';
00773          local_path = next_path+1;
00774         }
00775 
00776 // All done
00777 //
00778    return 0;
00779 }
00780 
00781 /******************************************************************************/
00782 /*                                   r e m                                    */
00783 /******************************************************************************/
00784   
00785 int XrdSfsNative::rem(const char             *path,    // In
00786                             XrdOucErrInfo    &error,   // Out
00787                       const XrdSecClientName *client,  // In
00788                       const char             *info)    // In
00789 /*
00790   Function: Delete a file from the namespace.
00791 
00792   Input:    path      - Is the fully qualified name of the file to be removed.
00793             einfo     - Error information object to hold error details.
00794             client    - Authentication credentials, if any.
00795             info      - Opaque information, if any.
00796 
00797   Output:   Returns SFS_OK upon success and SFS_ERROR upon failure.
00798 */
00799 {
00800    static const char *epname = "rem";
00801 
00802 // Perform the actual deletion
00803 //
00804     if (XrdSfsUFS::Rem(path) )
00805        return XrdSfsNative::Emsg(epname, error, errno, "remove", path);
00806 
00807 // All done
00808 //
00809     return SFS_OK;
00810 }
00811 
00812 /******************************************************************************/
00813 /*                                r e m d i r                                 */
00814 /******************************************************************************/
00815 
00816 int XrdSfsNative::remdir(const char             *path,    // In
00817                                XrdOucErrInfo    &error,   // Out
00818                          const XrdSecClientName *client,  // In
00819                          const char             *info)    // In
00820 /*
00821   Function: Delete a directory from the namespace.
00822 
00823   Input:    path      - Is the fully qualified name of the dir to be removed.
00824             einfo     - Error information object to hold error details.
00825             client    - Authentication credentials, if any.
00826             info      - Opaque information, if any.
00827 
00828   Output:   Returns SFS_OK upon success and SFS_ERROR upon failure.
00829 */
00830 {
00831    static const char *epname = "remdir";
00832 
00833 // Perform the actual deletion
00834 //
00835     if (XrdSfsUFS::Remdir(path) )
00836        return XrdSfsNative::Emsg(epname, error, errno, "remove", path);
00837 
00838 // All done
00839 //
00840     return SFS_OK;
00841 }
00842 
00843 /******************************************************************************/
00844 /*                                r e n a m e                                 */
00845 /******************************************************************************/
00846 
00847 int XrdSfsNative::rename(const char             *old_name,  // In
00848                          const char             *new_name,  // In
00849                                XrdOucErrInfo    &error,     //Out
00850                          const XrdSecClientName *client,    // In
00851                          const char             *infoO,     // In
00852                          const char             *infoN)     // In
00853 /*
00854   Function: Renames a file/directory with name 'old_name' to 'new_name'.
00855 
00856   Input:    old_name  - Is the fully qualified name of the file to be renamed.
00857             new_name  - Is the fully qualified name that the file is to have.
00858             error     - Error information structure, if an error occurs.
00859             client    - Authentication credentials, if any.
00860             info      - old_name opaque information, if any.
00861             info      - new_name opaque information, if any.
00862 
00863   Output:   Returns SFS_OK upon success and SFS_ERROR upon failure.
00864 */
00865 {
00866    static const char *epname = "rename";
00867 
00868 // Perform actual rename operation
00869 //
00870    if (XrdSfsUFS::Rename(old_name, new_name) )
00871       return XrdSfsNative::Emsg(epname, error, errno, "rename", old_name);
00872 
00873 // All done
00874 //
00875    return SFS_OK;
00876 }
00877   
00878 /******************************************************************************/
00879 /*                                  s t a t                                   */
00880 /******************************************************************************/
00881 
00882 int XrdSfsNative::stat(const char              *path,        // In
00883                              struct stat       *buf,         // Out
00884                              XrdOucErrInfo     &error,       // Out
00885                        const XrdSecClientName  *client,      // In
00886                        const char              *info)        // In
00887 /*
00888   Function: Get info on 'path'.
00889 
00890   Input:    path        - Is the fully qualified name of the file to be tested.
00891             buf         - The stat structiure to hold the results
00892             error       - Error information object holding the details.
00893             client      - Authentication credentials, if any.
00894             info        - Opaque information, if any.
00895 
00896   Output:   Returns SFS_OK upon success and SFS_ERROR upon failure.
00897 */
00898 {
00899    static const char *epname = "stat";
00900 
00901 // Execute the function
00902 //
00903    if (XrdSfsUFS::Statfn(path, buf) )
00904       return XrdSfsNative::Emsg(epname, error, errno, "state", path);
00905 
00906 // All went well
00907 //
00908    return SFS_OK;
00909 }
00910 
00911 /******************************************************************************/
00912 /*                              t r u n c a t e                               */
00913 /******************************************************************************/
00914   
00915 int XrdSfsNative::truncate(const char             *path,    // In
00916                                  XrdSfsFileOffset  flen,    // In
00917                                  XrdOucErrInfo    &error,   // Out
00918                            const XrdSecClientName *client,  // In
00919                            const char             *info)    // In
00920 /*
00921   Function: Set the length of the file object to 'flen' bytes.
00922 
00923   Input:    path      - The path to the file.
00924             flen      - The new size of the file.
00925             einfo     - Error information object to hold error details.
00926             client    - Authentication credentials, if any.
00927             info      - Opaque information, if any.
00928 
00929   Output:   Returns SFS_OK upon success and SFS_ERROR upon failure.
00930 
00931   Notes:    If 'flen' is smaller than the current size of the file, the file
00932             is made smaller and the data past 'flen' is discarded. If 'flen'
00933             is larger than the current size of the file, a hole is created
00934             (i.e., the file is logically extended by filling the extra bytes 
00935             with zeroes).
00936 */
00937 {
00938    static const char *epname = "trunc";
00939 
00940 // Make sure the offset is not too larg
00941 //
00942    if (sizeof(off_t) < sizeof(flen) && flen >  0x000000007fffffff)
00943       return XrdSfsNative::Emsg(epname, error, EFBIG, "truncate", path);
00944 
00945 // Perform the function
00946 //
00947    if (XrdSfsUFS::Truncate(path, flen) )
00948       return XrdSfsNative::Emsg(epname, error, errno, "truncate", path);
00949 
00950 // All done
00951 //
00952    return SFS_OK;
00953 }
00954 
00955 /******************************************************************************/
00956 /*                                  E m s g                                   */
00957 /******************************************************************************/
00958 
00959 int XrdSfsNative::Emsg(const char    *pfx,    // Message prefix value
00960                        XrdOucErrInfo &einfo,  // Place to put text & error code
00961                        int            ecode,  // The error code
00962                        const char    *op,     // Operation being performed
00963                        const char    *target) // The target (e.g., fname)
00964 {
00965     char *etext, buffer[MAXPATHLEN+80], unkbuff[64];
00966 
00967 // Get the reason for the error
00968 //
00969    if (ecode < 0) ecode = -ecode;
00970    if (!(etext = strerror(ecode)))
00971       {sprintf(unkbuff, "reason unknown (%d)", ecode); etext = unkbuff;}
00972 
00973 // Format the error message
00974 //
00975     snprintf(buffer,sizeof(buffer),"Unable to %s %s; %s", op, target, etext);
00976 
00977 // Print it out if debugging is enabled
00978 //
00979 #ifndef NODEBUG
00980    eDest->Emsg(pfx, buffer);
00981 #endif
00982 
00983 // Place the error message in the error object and return
00984 //
00985     einfo.setErrInfo(ecode, buffer);
00986 
00987     return SFS_ERROR;
00988 }

Generated on Tue Jul 5 14:47:02 2011 for ROOT_528-00b_version by  doxygen 1.5.1