#include <errno.h>
#ifdef WIN32
#include <io.h>
#endif
#include "TProofMgrLite.h"
#include "Riostream.h"
#include "TEnv.h"
#include "TError.h"
#include "TObjString.h"
#include "TProofLite.h"
#include "TProofLog.h"
#include "TROOT.h"
#include "TRegexp.h"
#include "TSortedList.h"
ClassImp(TProofMgrLite)
TProofMgrLite::TProofMgrLite(const char *url, Int_t dbg, const char *alias)
: TProofMgr(url, dbg, alias)
{
fServType = kProofLite;
}
TProof *TProofMgrLite::CreateSession(const char *cfg,
const char *, Int_t loglevel)
{
TString c(fUrl.GetOptions());
if (!c.Contains("workers=") && cfg && strstr(cfg, "workers=")) c = cfg;
Int_t nwrk = TProofLite::GetNumberOfWorkers(c);
if (nwrk == 0) return (TProof *)0;
if (gProof && gProof->IsLite()) {
if (gProof->IsValid()) {
if (nwrk > 0 && gProof->GetParallel() != nwrk) {
delete gProof;
gProof = 0;
} else {
return gProof;
}
} else {
delete gProof;
gProof = 0;
}
}
TString u("lite");
if (strlen(fUrl.GetOptions()) > 0) u.Form("lite/?%s", fUrl.GetOptions());
TProof *p = new TProofLite(u, cfg, 0, loglevel, 0, this);
if (p && p->IsValid()) {
Int_t ns = 1;
if (fSessions) {
if (fSessions->Last())
ns = ((TProofDesc *)(fSessions->Last()))->GetLocalId() + 1;
} else {
fSessions = new TList;
}
Int_t st = (p->IsIdle()) ? TProofDesc::kIdle : TProofDesc::kRunning ;
TProofDesc *d =
new TProofDesc(p->GetName(), p->GetTitle(), p->GetUrl(),
ns, p->GetSessionID(), st, p);
fSessions->Add(d);
} else {
Error("CreateSession", "creating PROOF session");
SafeDelete(p);
}
return p;
}
TProofLog *TProofMgrLite::GetSessionLogs(Int_t isess, const char *stag,
const char *pattern, Bool_t)
{
TProofLog *pl = 0;
isess = (isess < 0) ? -isess : isess;
bool retrieve = 1;
TString tag(stag);
if (tag == "NR") {
retrieve = 0;
tag = "";
}
TString sandbox(gSystem->WorkingDirectory());
sandbox.ReplaceAll(gSystem->HomeDirectory(),"");
sandbox.ReplaceAll("/","-");
sandbox.Replace(0,1,"/",1);
if (strlen(gEnv->GetValue("ProofLite.Sandbox", "")) > 0) {
sandbox.Insert(0, gEnv->GetValue("ProofLite.Sandbox", ""));
} else if (strlen(gEnv->GetValue("Proof.Sandbox", "")) > 0) {
sandbox.Insert(0, gEnv->GetValue("Proof.Sandbox", ""));
} else {
TString sb;
sb.Form("~/%s", kPROOF_WorkDir);
sandbox.Insert(0, sb.Data());
}
gSystem->ExpandPathName(sandbox);
TString sessiondir;
if (tag.Length() > 0) {
sessiondir.Form("%s/session-%s", sandbox.Data(), tag.Data());
if (gSystem->AccessPathName(sessiondir, kReadPermission)) {
Error("GetSessionLogs", "information for session '%s' not available", tag.Data());
return (TProofLog *)0;
}
} else {
TSortedList *olddirs = new TSortedList(kFALSE);
void *dirp = gSystem->OpenDirectory(sandbox);
if (dirp) {
const char *e = 0;
while ((e = gSystem->GetDirEntry(dirp))) {
if (!strncmp(e, "session-", 8)) {
TString d(e);
Int_t i = d.Last('-');
if (i != kNPOS) d.Remove(i);
i = d.Last('-');
if (i != kNPOS) d.Remove(0,i+1);
TString path = Form("%s/%s", sandbox.Data(), e);
olddirs->Add(new TNamed(d, path));
}
}
gSystem->FreeDirectory(dirp);
}
if (isess > olddirs->GetSize() - 1) {
Warning("GetSessionLogs",
"session index out of range (%d): take oldest available session", isess);
isess = olddirs->GetSize() - 1;
}
Int_t isx = isess;
TNamed *n = (TNamed *) olddirs->First();
while (isx-- > 0) {
olddirs->Remove(n);
delete n;
n = (TNamed *) olddirs->First();
}
if (!n) {
Error("GetSessionLogs", "cannot locate session dir for index '%d' under '%s':"
" cannot continue!", isess, sandbox.Data());
return (TProofLog *)0;
}
sessiondir = n->GetTitle();
tag = gSystem->BaseName(sessiondir);
tag.ReplaceAll("session-", "");
olddirs->SetOwner();
delete olddirs;
}
Info("GetSessionLogs", "analysing session dir %s", sessiondir.Data());
pl = new TProofLog(tag, "", this);
void *dirp = gSystem->OpenDirectory(sessiondir);
if (dirp) {
TSortedList *logs = new TSortedList;
const char *e = 0;
while ((e = gSystem->GetDirEntry(dirp))) {
TString fn(e);
if (fn.EndsWith(".log") && fn.CountChar('-') > 0) {
TString ord, url;
if (fn.BeginsWith("session-")) {
ord = "-1";
} else if (fn.BeginsWith("worker-")) {
ord = fn;
ord.ReplaceAll("worker-", "");
Int_t id = ord.First('-');
if (id != kNPOS) {
ord.Remove(id);
} else if (ord.Contains(".valgrind")) {
ord.ReplaceAll(".valgrind.log","-valgrind");
} else {
ord = "";
}
if (!ord.IsNull()) ord.ReplaceAll("0.", "");
}
if (!ord.IsNull()) {
url = Form("%s/%s", sessiondir.Data(), e);
logs->Add(new TNamed(ord, url));
if (gDebug > 1)
Info("GetSessionLogs", "ord: %s, url: %s", ord.Data(), url.Data());
}
}
}
gSystem->FreeDirectory(dirp);
TIter nxl(logs);
TNamed *n = 0;
while ((n = (TNamed *) nxl())) {
TString ord = Form("0.%s", n->GetName());
if (ord == "0.-1") ord = "0";
pl->Add(ord, n->GetTitle());
}
logs->SetOwner();
delete logs;
}
if (pl && retrieve) {
const char *pat = pattern ? pattern : "-v \"| SvcMsg\"";
if (pat && strlen(pat) > 0)
pl->Retrieve("*", TProofLog::kGrep, 0, pat);
else
pl->Retrieve();
}
return pl;
}
TObjString *TProofMgrLite::ReadBuffer(const char *fin, Long64_t ofs, Int_t len)
{
if (!fin || strlen(fin) <= 0) {
Error("ReadBuffer", "undefined path!");
return (TObjString *)0;
}
TString fn = TUrl(fin).GetFile();
Int_t fd = open(fn.Data(), O_RDONLY);
if (fd < 0) {
Error("ReadBuffer", "problems opening file %s", fn.Data());
return (TObjString *)0;
}
off_t start = 0, end = lseek(fd, (off_t) 0, SEEK_END);
if (ofs > 0 && ofs < end) {
start = lseek(fd, (off_t) ofs, SEEK_SET);
} else {
start = lseek(fd, (off_t) 0, SEEK_SET);
}
if (len > (end - start + 1) || len <= 0)
len = end - start + 1;
TString outbuf;
const Int_t kMAXBUF = 32768;
char buf[kMAXBUF];
Int_t left = len;
Int_t wanted = (left > kMAXBUF - 1) ? kMAXBUF - 1 : left;
do {
while ((len = read(fd, buf, wanted)) < 0 && TSystem::GetErrno() == EINTR)
TSystem::ResetErrno();
if (len < 0) {
Error("ReadBuffer", "error reading file %s", fn.Data());
close(fd);
return (TObjString *)0;
} else if (len > 0) {
if (len == wanted)
buf[len-1] = '\n';
buf[len] = '\0';
outbuf += buf;
}
left -= len;
wanted = (left > kMAXBUF - 1) ? kMAXBUF - 1 : left;
} while (len > 0 && left > 0);
close(fd);
return new TObjString(outbuf.Data());
}
TObjString *TProofMgrLite::ReadBuffer(const char *fin, const char *pattern)
{
if (!pattern || strlen(pattern) <= 0)
return (TObjString *)0;
if (!fin || strlen(fin) <= 0) {
Error("ReadBuffer", "undefined path!");
return (TObjString *)0;
}
TString fn = TUrl(fin).GetFile();
TString pat(pattern);
Bool_t excl = kFALSE;
if (pat.Contains("-v ")) {
pat.ReplaceAll("-v ", "");
excl = kTRUE;
}
pat = pat.Strip(TString::kLeading, ' ');
pat = pat.Strip(TString::kTrailing, ' ');
pat = pat.Strip(TString::kLeading, '\"');
pat = pat.Strip(TString::kTrailing, '\"');
TRegexp re(pat);
std::ifstream in;
in.open(fn.Data());
TString outbuf;
TString line;
while(in.good()) {
line.ReadLine(in);
if ((excl && line.Index(re) != kNPOS) ||
(!excl && line.Index(re) == kNPOS)) continue;
if (!line.EndsWith("\n")) line.Append('\n');
outbuf += line;
}
in.close();
return new TObjString(outbuf.Data());
}