XrdFrmAdminAudit.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                   X r d F r m A d m i n A u d i t . c c                    */
00004 /*                                                                            */
00005 /* (c) 2009 by the Board of Trustees of the Leland Stanford, Jr., University  */
00006 /*                            All Rights Reserved                             */
00007 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
00008 /*              DE-AC02-76-SFO0515 with the Department of Energy              */
00009 /******************************************************************************/
00010 
00011 //          $Id: XrdFrmAdminAudit.cc 32231 2010-02-05 18:24:46Z ganis $
00012 
00013 #include <stdio.h>
00014 #include <string.h>
00015 #include <sys/param.h>
00016 
00017 #include "XrdFrm/XrdFrmAdmin.hh"
00018 #include "XrdFrm/XrdFrmConfig.hh"
00019 #include "XrdFrm/XrdFrmFiles.hh"
00020 #include "XrdFrm/XrdFrmTrace.hh"
00021 #include "XrdFrm/XrdFrmUtils.hh"
00022 #include "XrdOss/XrdOssPath.hh"
00023 #include "XrdOss/XrdOssSpace.hh"
00024 #include "XrdOuc/XrdOucNSWalk.hh"
00025 #include "XrdOuc/XrdOucTList.hh"
00026 
00027 const char *XrdFrmAdminAuditCVSID = "$Id: XrdFrmAdminAudit.cc 32231 2010-02-05 18:24:46Z ganis $";
00028 
00029 using namespace XrdFrm;
00030 
00031 /******************************************************************************/
00032 /*                           A u d i t N a m e N B                            */
00033 /******************************************************************************/
00034 
00035 int XrdFrmAdmin::AuditNameNB(XrdFrmFileset *sP)
00036 {
00037    char Resp, buff[80];
00038    int num = 0, rem;
00039 
00040 // Report what is orphaned
00041 //
00042    if (sP->failFile())
00043       {num++; Msg("Orphaned fail file: ", sP->failPath());}
00044    if (sP->lockFile())
00045       {num++; Msg("Orphaned lock file: ", sP->lockPath());}
00046    if (sP->pfnFile() )
00047       {num++; Msg("Orphaned pfn  file: ", sP->pfnPath());
00048               Msg("PFN file refers to: ", sP->pfnFile()->Link);
00049                  }
00050    if (sP->pinFile() )
00051       {num++; Msg("Orphaned pin  file: ", sP->pinPath());}
00052 
00053 // Return if no fix is needed, otherwise check if we should ask before removal
00054 //
00055    numProb += num;
00056    if (!Opt.Fix || !num) return 1;
00057    if (!Opt.Force)
00058       {Resp = XrdFrmUtils::Ask('n', "Remove orphaned files?");
00059        if (Resp != 'y') return Resp != 'a';
00060       }
00061 
00062 // Remove the orphaned files
00063 //
00064    rem = AuditRemove(sP);
00065    numFix += rem;
00066 
00067 // Indicate final resolution
00068 //
00069    sprintf(buff, "%d of %d orphaned files removed.", rem, num);
00070    Msg(buff);
00071    return 1;
00072 }
00073   
00074 /******************************************************************************/
00075 /*                           A u d i t N a m e N F                            */
00076 /******************************************************************************/
00077 
00078 int XrdFrmAdmin::AuditNameNF(XrdFrmFileset *sP)
00079 {
00080    char Resp;
00081 
00082 // Indicate what is wrong
00083 //
00084    Msg("Dangling link:  ", sP->basePath());
00085    Msg("Missing target: ", sP->baseFile()->Link);
00086    numProb++;
00087 
00088 // Return if no fix is needed, otherwise check if we should ask before removal
00089 //
00090    if (!Opt.Fix) return 1;
00091    if (!Opt.Force)
00092       {Resp = XrdFrmUtils::Ask('n', "Remove symlink?");
00093        if (Resp != 'y') return Resp != 'a';
00094       }
00095 
00096 // Remove the symlink and associated files
00097 //
00098    if (unlink(sP->basePath()))
00099       Emsg(errno,"remove symlink", sP->basePath());
00100       else if (AuditRemove(sP))
00101               {Msg("Symlink removed.");
00102                numFix++;
00103                return 1;
00104               }
00105    return 1;
00106 }
00107   
00108 /******************************************************************************/
00109 /*                           A u d i t N a m e N L                            */
00110 /******************************************************************************/
00111 
00112 int XrdFrmAdmin::AuditNameNL(XrdFrmFileset *sP)
00113 {
00114    char Resp;
00115 
00116 // Indicate what is wrong
00117 //
00118    Msg("Missing lock file: ", sP->basePath());
00119    numProb++;
00120 
00121 // Return if no fix is needed, otherwise check if we should ask before removal
00122 //
00123    if (!Opt.Fix) return -1;
00124    if (!Opt.Force)
00125       {Resp = XrdFrmUtils::Ask('y', "Create lock file?");
00126        if (Resp != 'y') return Resp != 'a';
00127       }
00128 
00129 // Create the lock file
00130 //
00131    if (!mkFile(mkLF|isPFN, sP->basePath())) return 1;
00132    Msg("Lock file created.");
00133    numFix++;
00134    return 1;
00135 }
00136 
00137 /******************************************************************************/
00138 /*                            A u d i t N a m e s                             */
00139 /******************************************************************************/
00140   
00141 int XrdFrmAdmin::AuditNames()
00142 {
00143    XrdFrmFileset *sP;
00144    XrdFrmFiles   *fP;
00145    char pDir[MAXPATHLEN], *lDir = Opt.Args[1];
00146    int opts = (Opt.Recurse ? XrdFrmFiles::Recursive : 0);
00147    int ec = 0, Act = 1;
00148 
00149 // Initialization
00150 //
00151    numProb = 0; numFix = 0;
00152    if (VerifyMP("audit", lDir) != 'y') return 0;
00153 
00154 // Process the directory
00155 //
00156    if (!Config.LocalPath(lDir, pDir, sizeof(pDir))) {finalRC = 4; return 1;}
00157    fP = new XrdFrmFiles(pDir, opts);
00158    while(Act && (sP = fP->Get(ec,1)))
00159         {if (!(sP->baseFile())) Act = AuditNameNB(sP);
00160              else {if (sP->baseFile()->Type == XrdOucNSWalk::NSEnt::isLink)
00161                       Act = AuditNameNF(sP);
00162                    if (Act && Opt.MPType && !(sP->lockFile()))
00163                       Act = AuditNameNL(sP);
00164                    if (Act && sP->baseFile()->Link && isXA(sP->baseFile()))
00165                       Act = AuditNameXA(sP);
00166                   }
00167          }
00168     if (ec) finalRC = 4;
00169     delete fP;
00170 
00171 // All done
00172 //
00173    if (!Act) Msg("Audit names aborted!");
00174    sprintf(pDir,"%d problem%s found; %d fixed.", numProb,
00175                 (numProb == 1 ? "" : "s"), numFix);
00176    Msg(pDir);
00177    return !Act;
00178 }
00179 
00180 /******************************************************************************/
00181 /*                           A u d i t N a m e X A                            */
00182 /******************************************************************************/
00183   
00184 int XrdFrmAdmin::AuditNameXA(XrdFrmFileset *sP)
00185 {
00186    struct stat buf;
00187    char Path[1032], lkbuff[1032];
00188    int n;
00189 
00190 // Make sure there is a PFN file here
00191 //
00192    strcpy(Path, sP->baseFile()->Link); strcat(Path, ".pfn");
00193    if (lstat(Path,&buf))
00194       {if (errno != ENOENT)
00195           {Emsg(errno, "stat ", Path); return AuditNameXL(sP,-1);}
00196        Msg("Missing pfn link to ", sP->basePath());
00197        return AuditNameXL(sP,0);
00198       }
00199 
00200 // Make sure the PFN file is a link
00201 //
00202    if ((buf.st_mode & S_IFMT) != S_IFLNK)
00203       {Msg("Invalid pfn file for ", sP->basePath());
00204        return AuditNameXL(sP,1);
00205       }
00206 
00207 // Make sure the link points to the right file
00208 //
00209    if ((n = readlink(Path, lkbuff, sizeof(lkbuff)-1)) < 0)
00210       {Emsg(errno, "read link from ", Path); return AuditNameXL(sP,-1);}
00211    lkbuff[n] = '\0';
00212    if (strcmp(sP->basePath(), lkbuff))
00213       {Msg("Incorrect pfn link to ", sP->basePath());
00214        return AuditNameXL(sP,1);
00215       }
00216 
00217 // All is well
00218 //
00219    return 1;
00220 }
00221 
00222 /******************************************************************************/
00223 /*                           A u d i t N a m e X L                            */
00224 /******************************************************************************/
00225   
00226 int XrdFrmAdmin::AuditNameXL(XrdFrmFileset *sP, int dorm)
00227 {
00228    char Resp, Path[1032];
00229 
00230 // Return if no fix is needed, otherwise check if we should ask before doing it
00231 //
00232    numProb++;
00233    if (!Opt.Fix || dorm < 0) return 1;
00234    if (!Opt.Force)
00235       {if (dorm)
00236           Resp = XrdFrmUtils::Ask('n', "Recreate pfn symlink?");
00237           else
00238           Resp = XrdFrmUtils::Ask('y',   "Create pfn symlink?");
00239        if (Resp != 'y') return Resp != 'a';
00240       }
00241 
00242 // Create the pfn symlink
00243 //
00244    strcpy(Path, sP->baseFile()->Link); strcat(Path, ".pfn");
00245    if (dorm) unlink(Path);
00246    if (symlink(sP->basePath(), Path))
00247       {Emsg(errno, "create symlink ", Path); return 1;}
00248    Msg("pfn symlink created.");
00249    numFix++;
00250    return 1;
00251 }
00252 
00253 /******************************************************************************/
00254 /*                           A u d i t R e m o v e                            */
00255 /******************************************************************************/
00256   
00257 int XrdFrmAdmin::AuditRemove(XrdFrmFileset *sP)
00258 {
00259    int rem = 0;
00260 
00261 // Remove the orphaned files
00262 //
00263    if (sP->failFile())
00264       {if (unlink(sP->failPath())) Emsg(errno,"remove fail file.");
00265           else rem++;
00266       }
00267    if (sP->lockFile())
00268       {if (unlink(sP->lockPath())) Emsg(errno,"remove lock file.");
00269           else rem++;
00270       }
00271    if (sP-> pinFile())
00272       {if (unlink(sP-> pinPath())) Emsg(errno,"remove pin  file.");
00273           else rem++;
00274       }
00275    if (sP-> pfnFile())
00276       {if (unlink(sP-> pinPath())) Emsg(errno,"remove pfn  file.");
00277           else rem++;
00278       }
00279 
00280    return rem;
00281 }
00282 
00283 /******************************************************************************/
00284 /*                            A u d i t S p a c e                             */
00285 /******************************************************************************/
00286   
00287 int XrdFrmAdmin::AuditSpace()
00288 {
00289    XrdOucTList   *pP;
00290    char buff[256], *Path = 0, *Space = Opt.Args[1];
00291    int Act;
00292 
00293 // Parse the space specification
00294 //
00295    if (!(pP = ParseSpace(Space, &Path))) return 4;
00296 
00297 // Initialize
00298 //
00299    numBytes = 0; numFiles = 0; numProb = 0; numFix = 0;
00300 
00301 // Index the space via filesets
00302 //
00303    do {Act = (pP->val ? AuditSpaceXA(Space, pP->text) : AuditSpaceAX(pP->text));
00304        pP = pP->next;
00305       } while(pP && !Path && Act);
00306 
00307 // All done
00308 //
00309    sprintf(buff,"%d problem%s found; %d fixed.", numProb,
00310                 (numProb == 1 ? "" : "s"), numFix);
00311    Msg(buff);
00312    if (!Act) Msg("Audit space aborted!");
00313       else {if (Path) *(--Path) = ':';
00314             sprintf(buff, "Space %s has %d file%s with %lld byte%s in use.",
00315                     Space,
00316                     numFiles, (numFiles == 1 ? "" : "s"),
00317                     numBytes, (numBytes == 1 ? "" : "s"));
00318             Msg(buff);
00319            }
00320    return (Act ? 0 : 4);
00321 }
00322 
00323 /******************************************************************************/
00324 /*                          A u d i t S p a c e A X                           */
00325 /******************************************************************************/
00326   
00327 int XrdFrmAdmin::AuditSpaceAX(const char *Path)
00328 {
00329    XrdOucNSWalk nsWalk(&Say, Path, Config.lockFN, XrdOucNSWalk::retFile
00330                                                 | XrdOucNSWalk::retStat
00331                                                 | XrdOucNSWalk::skpErrs);
00332    XrdOucNSWalk::NSEnt *nP, *pP;
00333    char buff[1032];
00334    int ec, Act = 1;
00335 
00336 // Get the files in this directory
00337 //
00338    if (!(nP = nsWalk.Index(ec))) {if (ec) finalRC = 4; return 1;}
00339    pP = nP;
00340 
00341 // Now traverse through all of the files
00342 //
00343    while(nP && Act)
00344         {Act = (XrdOssPath::genPFN(buff, sizeof(buff), nP->Path)
00345              ? AuditSpaceAXDC(buff, nP) : AuditSpaceAXDB(nP->Path));
00346          nP = nP->Next;
00347         }
00348 
00349 // Delete the entries and return
00350 //
00351    while(pP) {nP = pP; pP = pP->Next; delete nP;}
00352    return Act;
00353 }
00354 
00355 /******************************************************************************/
00356 /*                        A u d i t S p a c e A X D B                         */
00357 /******************************************************************************/
00358   
00359 int XrdFrmAdmin::AuditSpaceAXDB(const char *Path)
00360 {
00361    char Resp;
00362 
00363 // Indicate the problem
00364 //
00365    Msg("Invalid name for data file ", Path);
00366    numProb++;
00367 
00368 // Return if no fix is needed, otherwise check if we should ask before doing it
00369 //
00370    if (Opt.Fix)
00371       {if (!Opt.Force)
00372           {Resp = XrdFrmUtils::Ask('n', "Delete file?");
00373            if (Resp != 'y') return Resp != 'a';
00374           }
00375        if (unlink(Path)) Emsg(errno, "remove ", Path);
00376           else numFix++;
00377       }
00378    return 1;
00379 }
00380 
00381 /******************************************************************************/
00382 /*                        A u d i t S p a c e A X D C                         */
00383 /******************************************************************************/
00384   
00385 int XrdFrmAdmin::AuditSpaceAXDC(const char *Path, XrdOucNSWalk::NSEnt *nP)
00386 {
00387    struct stat buf;
00388    char lkbuff[1032], *Dest = nP->Path;
00389    int n;
00390 
00391 // Assume we have a problem
00392 //
00393    numProb++;
00394 
00395 // Verify that the link to the file exists
00396 //
00397    if (lstat(Path,&buf))
00398       {if (errno != ENOENT) {Emsg(errno, "stat ", Path); return 1;}
00399        Msg("Missing pfn data link ", Path);
00400        return AuditSpaceAXDL(0, Path, Dest);
00401       }
00402 
00403 // Make sure the PFN file is a link
00404 //
00405    if ((buf.st_mode & S_IFMT) != S_IFLNK)
00406       {Msg("Invalid pfn data link ", Path);
00407        return AuditSpaceAXDL(1, Path, Dest);
00408       }
00409 
00410 // Make sure tyhe link points to the right file
00411 //
00412    if ((n = readlink(Path, lkbuff, sizeof(lkbuff)-1)) < 0)
00413       {Emsg(errno, "read link from ", Path); return 1;}
00414    lkbuff[n] = '\0';
00415    if (strcmp(Path, lkbuff))
00416       {Msg("Incorrect pfn data link ", Path);
00417        return AuditSpaceAXDL(1, Path, Dest);
00418       }
00419 
00420 // All went well
00421 //
00422    numProb--; numFiles++; numBytes += nP->Stat.st_size;
00423    return 1;
00424 }
00425 
00426 /******************************************************************************/
00427 /*                        A u d i t S p a c e A X D L                         */
00428 /******************************************************************************/
00429   
00430 int XrdFrmAdmin::AuditSpaceAXDL(int dorm, const char *Path, const char *Dest)
00431 {
00432    char Resp;
00433 
00434 // Return if no fix is needed, otherwise check if we should ask before doing it
00435 //
00436    if (!Opt.Fix) return -1;
00437    if (!Opt.Force)
00438       {if (dorm)
00439           Resp = XrdFrmUtils::Ask('n', "Recreate pfn symlink?");
00440           else
00441           Resp = XrdFrmUtils::Ask('y',   "Create pfn symlink?");
00442        if (Resp != 'y') return Resp != 'a';
00443       }
00444 
00445 // Create the pfn symlink
00446 //
00447    if (dorm) unlink(Path);
00448    if (symlink(Dest, Path))
00449       {Emsg(errno, "create symlink ", Path); return 1;}
00450    Msg("pfn symlink created.");
00451    numFix++;
00452    return 1;
00453 }
00454 
00455 /******************************************************************************/
00456 /*                          A u d i t S p a c e X A                           */
00457 /******************************************************************************/
00458   
00459 int XrdFrmAdmin::AuditSpaceXA(const char *Space, const char *Path)
00460 {
00461    XrdFrmFileset *sP;
00462    XrdFrmFiles   *fP;
00463    char tmpv[8], *buff;
00464    int ec = 0, Act = 1;
00465 
00466 // Construct the right space path and get a files object
00467 //
00468    buff = XrdOssPath::genPath(Path, Space, tmpv);
00469    fP = new XrdFrmFiles(buff, XrdFrmFiles::Recursive);
00470 
00471 // Go and check out the files
00472 //
00473    while(Act && (sP = fP->Get(ec,1)))
00474         {     if (!(sP->baseFile())) Act = AuditNameNB(sP);
00475          else if (!(sP-> pfnFile())) Act = AuditSpaceXANB(sP);
00476          else {numFiles++; numBytes += sP->baseFile()->Stat.st_size; continue;}
00477         }
00478 
00479 // All done
00480 //
00481    if (ec) finalRC = 4;
00482    free(buff);
00483    delete fP;
00484    return Act;
00485 }
00486 
00487 /******************************************************************************/
00488 /*                        A u d i t S p a c e X A N B                         */
00489 /******************************************************************************/
00490 
00491 int XrdFrmAdmin::AuditSpaceXANB(XrdFrmFileset *sP)
00492 {
00493    char Resp;
00494 
00495 // Update statistics which we may have to correct later
00496 //
00497    numProb++; numFiles++; numBytes += sP->baseFile()->Stat.st_size;
00498 
00499 // Report what is orphaned
00500 //
00501    Msg("Missing pfn file for data file ", sP->basePath());
00502 
00503 // Return if no fix is needed, otherwise check if we should ask before removal
00504 //
00505    if (!Opt.Fix) return -1;
00506    if (!Opt.Force)
00507       {Resp = XrdFrmUtils::Ask('n', "Remove data file?");
00508        if (Resp != 'y') return Resp != 'a';
00509       }
00510 
00511 // Remove the file
00512 //
00513    if (unlink(sP->basePath())) Emsg(errno,"remove data file ", sP->basePath());
00514       else {numFix++; numFiles--; numBytes -= sP->baseFile()->Stat.st_size;}
00515    return 1;
00516 }
00517   
00518 /******************************************************************************/
00519 /*                            A u d i t U s a g e                             */
00520 /******************************************************************************/
00521   
00522 int XrdFrmAdmin::AuditUsage()
00523 {
00524    XrdFrmConfig::VPInfo *vP = Config.VPList;
00525    char Sbuff[1024];
00526    int retval, rc;
00527 
00528 // Check if we have a space or we should do all spaces
00529 //
00530    if (Opt.Args[1]) return AuditUsage(Opt.Args[1]);
00531 
00532 // If no cache configured say so
00533 //
00534    if (!vP) {Emsg("No outplace space has been configured."); return -1;}
00535 
00536 // Audit usage for each space
00537 //
00538    retval = 1;
00539    while(vP) 
00540         {strcpy(Sbuff, vP->Name);
00541          if (!(rc = AuditUsage(Sbuff))) return 0;
00542          if (rc < 0) retval = rc;
00543          vP = vP->Next;
00544         }
00545    return retval;
00546 }
00547   
00548 /******************************************************************************/
00549   
00550 int XrdFrmAdmin::AuditUsage(char *Space)
00551 {
00552    XrdOucTList   *pP;
00553    const char *Sfx;
00554    char Resp, buff[256], *Path = 0;
00555    long long theClaim, theDiff;
00556    int haveUsage, Probs = 0;
00557 
00558 // Parse the space specification
00559 //
00560    if (!(pP = ParseSpace(Space, &Path))) return -1;
00561    if (Path) {Emsg("Path not allowed for audit usage."); return -1;}
00562 
00563 // Initialize
00564 //
00565    numBytes = 0; numFiles = 0; numProb = 0;
00566    haveUsage = XrdOssSpace::Init();
00567 
00568 // Index the space via filesets
00569 //
00570    do {Probs |= (pP->val ? AuditUsageXA(pP->text, Space)
00571                          : AuditUsageAX(pP->text));
00572        pP = pP->next;
00573       } while(pP);
00574 
00575 // Print ending condition
00576 //
00577    sprintf(buff, "Audit of %d file%s in %s space completed with %serrors.",
00578                  numFiles, (numFiles == 1 ? "" : "s"), Space,
00579                  (Probs ? "" : "no "));
00580    Msg(buff);
00581 
00582 // Print what is in the usage file
00583 //
00584    if (haveUsage)
00585       {XrdOssSpace::uEnt myEnt;
00586        XrdOssSpace::Usage(Space, myEnt);
00587        theClaim = myEnt.Bytes[XrdOssSpace::Serv]
00588                 + myEnt.Bytes[XrdOssSpace::Pstg]
00589                 - myEnt.Bytes[XrdOssSpace::Purg]
00590                 + myEnt.Bytes[XrdOssSpace::Admin];
00591        sprintf(buff, "%12lld", theClaim);
00592        Msg("Claimed: ", buff);
00593       } else theClaim = numBytes;
00594 
00595 // Print what we came up with
00596 //
00597    sprintf(buff, "%12lld", numBytes);
00598    Msg("Actual:  ", buff);
00599 
00600 // Check if fix is required and wanted
00601 //
00602    if (numBytes == theClaim || !Opt.Fix) return 1;
00603    if (!haveUsage)
00604       {Emsg(0, "No usage file present to fix!"); return -1;}
00605 
00606 // Compute difference
00607 //
00608    if (theClaim < numBytes) theDiff = numBytes - theClaim;
00609       else                  theDiff = theClaim - numBytes;
00610 
00611 // See if we should fix this
00612 //
00613    if (!Opt.Force)
00614       {if (theDiff < 500000) Sfx = "byte";
00615           {theDiff = (theDiff+512)/1024; Sfx = "KB";}
00616        sprintf(buff, "Fix %lld %s difference?", theDiff, Sfx);
00617        Resp = XrdFrmUtils::Ask('n', "Fix usage information?");
00618        if (Resp != 'y') return Resp != 'a';
00619       }
00620 
00621 // Fix the problem
00622 //
00623    XrdOssSpace::Adjust(Space, numBytes-theClaim, XrdOssSpace::Admin);
00624    return 1;
00625 }
00626 
00627 /******************************************************************************/
00628 /*                          A u d i t U s a g e A X                           */
00629 /******************************************************************************/
00630   
00631 int XrdFrmAdmin::AuditUsageAX(const char *Path)
00632 {
00633    XrdOucNSWalk nsWalk(&Say, Path, Config.lockFN, XrdOucNSWalk::retFile
00634                                                 | XrdOucNSWalk::retStat
00635                                                 | XrdOucNSWalk::skpErrs);
00636    XrdOucNSWalk::NSEnt *nP, *pP;
00637    int ec;
00638 
00639 // Get the files in this directory
00640 //
00641    if (!(nP = nsWalk.Index(ec))) {if (ec) finalRC = 4; return 1;}
00642 
00643 // Now traverse through all of the files
00644 //
00645    while(nP)
00646         {numBytes += nP->Stat.st_size;
00647          numFiles++;
00648          pP = nP;
00649          nP = nP->Next;
00650          delete pP;
00651         }
00652 
00653 // All done
00654 //
00655    return 0;
00656 }
00657 
00658 /******************************************************************************/
00659 /*                          A u d i t U s a g e X A                           */
00660 /******************************************************************************/
00661   
00662 int XrdFrmAdmin::AuditUsageXA(const char *Path, const char *Space)
00663 {
00664    XrdFrmFileset *sP;
00665    XrdFrmFiles   *fP;
00666    char tmpv[8], *buff;
00667    int ec = 0;
00668 
00669 // Construct the right space path and get a files object
00670 //
00671    buff = XrdOssPath::genPath(Path, Space, tmpv);
00672    fP = new XrdFrmFiles(buff, XrdFrmFiles::Recursive);
00673 
00674 // Go and check out the files
00675 //
00676    while((sP = fP->Get(ec)))
00677         {if ((sP->baseFile()))
00678             {numFiles++; numBytes += sP->baseFile()->Stat.st_size;}
00679         }
00680 
00681 // All done
00682 //
00683    free(buff);
00684    delete fP;
00685    return ec;
00686 }
00687   
00688 /******************************************************************************/
00689 /*                                  i s X A                                   */
00690 /******************************************************************************/
00691   
00692 int XrdFrmAdmin::isXA(XrdOucNSWalk::NSEnt *nP)
00693 {
00694    char *lP;
00695 
00696    if (!(nP->Link)) return 0;
00697    lP = nP->Link + nP->Lksz -1;
00698    return (*lP == XrdOssPath::xChar);
00699 }

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