/******************************************************************************/
/* */
/* X r d C n s L o g . c c */
/* */
/* (c) 2011 by the Board of Trustees of the Leland Stanford, Jr., University */
/* All Rights Reserved */
/* Produced by Andrew Hanushevsky for Stanford University under contract */
/* DE-AC02-76-SFO0515 with the Department of Energy */
/* */
/* This file is part of the XRootD software suite. */
/* */
/* XRootD is free software: you can redistribute it and/or modify it under */
/* the terms of the GNU Lesser General Public License as published by the */
/* Free Software Foundation, either version 3 of the License, or (at your */
/* option) any later version. */
/* */
/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
/* License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public License */
/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
/* COPYING (GPL license). If not, see . */
/* */
/* The copyright holder's institutional names and contributor's names may not */
/* be used to endorse or promote products derived from this software without */
/* specific prior written permission of the institution or contributor. */
/******************************************************************************/
#include
#include
#include
#include
#include
#include
#include "XrdCns/XrdCnsLog.hh"
#include "XrdCns/XrdCnsLogRec.hh"
#include "XrdNet/XrdNetAddr.hh"
#include "XrdOuc/XrdOucTList.hh"
/******************************************************************************/
/* G l o b a l O b j e c t s */
/******************************************************************************/
const char *XrdCnsLog::invFNa = "inv.log";
const char *XrdCnsLog::invFNt = "inventory";
const char *XrdCnsLog::invFNz = "Inventory";
namespace XrdCns
{
extern XrdSysError MLog;
}
using namespace XrdCns;
/******************************************************************************/
/* D i r s */
/******************************************************************************/
XrdOucTList *XrdCnsLog::Dirs(const char *Path, int &rc)
{
XrdOucNSWalk lDir(&MLog, Path, 0, XrdOucNSWalk::retDir
|XrdOucNSWalk::Recurse);
XrdOucNSWalk::NSEnt *nsP, *ntP;
XrdOucTList *dList = 0;
const char *fnP;
// Convert this to a file
//
if ((fnP = rindex(Path, '/'))) fnP++;
else fnP = Path;
// If the incomming path is an endpoint then just return it
//
if (isEP(fnP)) return new XrdOucTList(Path, fnP-Path);
// Now get all of the directories
//
while((nsP = lDir.Index(rc)))
do {if (isEP(nsP->File))
dList = new XrdOucTList(nsP->Path,nsP->File-nsP->Path,dList);
ntP = nsP; nsP = nsP->Next; delete ntP;
} while(nsP);
// All done
//
return dList;
}
/******************************************************************************/
/* L i s t */
/******************************************************************************/
XrdOucNSWalk::NSEnt *XrdCnsLog::List(const char *logDir,
XrdOucNSWalk::NSEnt **Base,
int isEP)
{
XrdOucNSWalk lDir(&MLog, logDir, 0, XrdOucNSWalk::retFile
|XrdOucNSWalk::retStat);
XrdOucNSWalk::NSEnt *nInv = 0, *nFirst = 0, *sP, *psP, *nsP, *ntP;
const char *msg, *iFN = (isEP ? invFNz : invFNt);
int rc;
// Now get all of the files in the directory
//
nsP = lDir.Index(rc);
if (rc) return 0;
// Construct list of pending log files
//
while((ntP = nsP))
{nsP = nsP->Next;
if (isEP && *(ntP->File) == '.') {delete ntP; continue;}
if (!strcmp(iFN, ntP->File) && !nInv && ntP->Stat.st_size)
{nInv = ntP; continue;}
rc = atoi(ntP->File+8);
if (ntP->Stat.st_size == 0
|| strncmp("cns.log.", ntP->File, 8)
|| rc < 0 || rc >= XrdCnsLogRec::maxClients || *(ntP->File+9) != '.')
{if (!isEP)
{msg = (ntP->Stat.st_size ? "Removing improper log file"
: "Removing empty log file");
MLog.Emsg("List", msg, ntP->Path);
unlink(ntP->Path);
}
delete ntP; continue;
}
sP = nFirst; psP = 0; ntP->Next = 0; ntP->Stat.st_nlink = rc;
while(sP && sP->Stat.st_ctime < ntP->Stat.st_ctime)
{psP = sP; sP = sP->Next;}
ntP->Next = sP;
if (psP) psP->Next = ntP;
else nFirst = ntP;
}
// Return whatever information we have
//
*Base = nInv;
return nFirst;
}
/******************************************************************************/
/* P r i v a t e M e t h o d s */
/******************************************************************************/
/******************************************************************************/
/* i s E P */
/******************************************************************************/
int XrdCnsLog::isEP(const char *File)
{
XrdNetAddr tAddr;
const char *dotP;
// An endpoint must be a valid host name
//
if (!(dotP = index(File,'.')) || dotP == rindex(File,'.')) return 0;
return (tAddr.Set(File,0) == 0);
}