#include "RConfigure.h"
#include "RConfig.h"
#include "Riostream.h"
#ifdef WIN32
#include <io.h>
typedef long off_t;
#endif
#include <errno.h>
#include <time.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#if (defined(__FreeBSD__) && (__FreeBSD__ < 4)) || \
(defined(__APPLE__) && (!defined(MAC_OS_X_VERSION_10_3) || \
(MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3)))
#include <sys/file.h>
#define lockf(fd, op, sz) flock((fd), (op))
#ifndef F_LOCK
#define F_LOCK (LOCK_EX | LOCK_NB)
#endif
#ifndef F_ULOCK
#define F_ULOCK LOCK_UN
#endif
#endif
#include "RRemoteProtocol.h"
#include "TApplicationServer.h"
#include "TBenchmark.h"
#include "TEnv.h"
#include "TError.h"
#include "TException.h"
#include "TInterpreter.h"
#include "TMD5.h"
#include "TMessage.h"
#include "TROOT.h"
#include "TSocket.h"
#include "TSystem.h"
#include "TRemoteObject.h"
#include "TUrl.h"
#include "TObjString.h"
#include "compiledata.h"
#include "TClass.h"
class TASInterruptHandler : public TSignalHandler {
TApplicationServer *fServ;
public:
TASInterruptHandler(TApplicationServer *s)
: TSignalHandler(kSigUrgent, kFALSE) { fServ = s; }
Bool_t Notify();
};
Bool_t TASInterruptHandler::Notify()
{
fServ->HandleUrgentData();
if (TROOT::Initialized()) {
Throw(GetSignal());
}
return kTRUE;
}
class TASSigPipeHandler : public TSignalHandler {
TApplicationServer *fServ;
public:
TASSigPipeHandler(TApplicationServer *s) : TSignalHandler(kSigPipe, kFALSE)
{ fServ = s; }
Bool_t Notify();
};
Bool_t TASSigPipeHandler::Notify()
{
fServ->HandleSigPipe();
return kTRUE;
}
class TASInputHandler : public TFileHandler {
TApplicationServer *fServ;
public:
TASInputHandler(TApplicationServer *s, Int_t fd) : TFileHandler(fd, 1)
{ fServ = s; }
Bool_t Notify();
Bool_t ReadNotify() { return Notify(); }
};
Bool_t TASInputHandler::Notify()
{
fServ->HandleSocketInput();
return kTRUE;
}
TString TASLogHandler::fgPfx = "";
TASLogHandler::TASLogHandler(const char *cmd, TSocket *s, const char *pfx)
: TFileHandler(-1, 1), fSocket(s), fPfx(pfx)
{
ResetBit(kFileIsPipe);
fFile = 0;
if (s && cmd) {
fFile = gSystem->OpenPipe(cmd, "r");
if (fFile) {
SetFd(fileno(fFile));
Notify();
SetBit(kFileIsPipe);
} else {
fSocket = 0;
Error("TASLogHandler", "executing command in pipe");
}
} else {
Error("TASLogHandler",
"undefined command (%p) or socket (%p)", (int *)cmd, s);
}
}
TASLogHandler::TASLogHandler(FILE *f, TSocket *s, const char *pfx)
: TFileHandler(-1, 1), fSocket(s), fPfx(pfx)
{
ResetBit(kFileIsPipe);
fFile = 0;
if (s && f) {
fFile = f;
SetFd(fileno(fFile));
Notify();
} else {
Error("TASLogHandler", "undefined file (%p) or socket (%p)", f, s);
}
}
TASLogHandler::~TASLogHandler()
{
if (TestBit(kFileIsPipe) && fFile)
gSystem->ClosePipe(fFile);
fFile = 0;
fSocket = 0;
ResetBit(kFileIsPipe);
}
Bool_t TASLogHandler::Notify()
{
if (IsValid()) {
TMessage m(kMESS_ANY);
char line[4096];
char *plf = 0;
while (fgets(line, sizeof(line), fFile)) {
if ((plf = strchr(line, '\n')))
*plf = 0;
m.Reset(kMESS_ANY);
m << (Int_t)kRRT_Message;
if (fPfx.Length() > 0) {
m << TString(Form("%s: %s", fPfx.Data(), line));
} else if (fgPfx.Length() > 0) {
m << TString(Form("%s: %s", fgPfx.Data(), line));
} else {
m << TString(line);
}
fSocket->Send(m);
}
}
return kTRUE;
}
void TASLogHandler::SetDefaultPrefix(const char *pfx)
{
fgPfx = pfx;
}
TASLogHandlerGuard::TASLogHandlerGuard(const char *cmd, TSocket *s,
const char *pfx, Bool_t on)
{
fExecHandler = 0;
if (cmd && on) {
fExecHandler = new TASLogHandler(cmd, s, pfx);
if (fExecHandler->IsValid()) {
gSystem->AddFileHandler(fExecHandler);
} else {
Error("TASLogHandlerGuard","invalid handler");
}
} else {
if (on)
Error("TASLogHandlerGuard","undefined command");
}
}
TASLogHandlerGuard::TASLogHandlerGuard(FILE *f, TSocket *s,
const char *pfx, Bool_t on)
{
fExecHandler = 0;
if (f && on) {
fExecHandler = new TASLogHandler(f, s, pfx);
if (fExecHandler->IsValid()) {
gSystem->AddFileHandler(fExecHandler);
} else {
Error("TASLogHandlerGuard","invalid handler");
}
} else {
if (on)
Error("TASLogHandlerGuard","undefined file");
}
}
TASLogHandlerGuard::~TASLogHandlerGuard()
{
if (fExecHandler && fExecHandler->IsValid()) {
gSystem->RemoveFileHandler(fExecHandler);
SafeDelete(fExecHandler);
}
}
ClassImp(TApplicationServer)
TApplicationServer::TApplicationServer(Int_t *argc, char **argv,
FILE *flog, const char *logfile)
: TApplication("server", argc, argv, 0, -1)
{
GetOptions(argc, argv);
gErrorAbortLevel = kSysError + 1;
SetErrorHandler(ErrorHandler);
fInterrupt = kFALSE;
fSocket = 0;
fWorkingDir = 0;
fLogFilePath = logfile;
fLogFile = flog;
fLogFileDes = -1;
if (!fLogFile || (fLogFileDes = fileno(fLogFile)) < 0)
Terminate(0);
fRealTimeLog = kFALSE;
fSentCanvases = 0;
TASLogHandler::SetDefaultPrefix(Form("roots:%s", gSystem->HostName()));
fIsValid = kFALSE;
if (!(fSocket = new TSocket(GetHost(), GetPort()))) {
Terminate(0);
return;
}
Int_t sock = fSocket->GetDescriptor();
if (Setup() != 0) {
Error("TApplicationServer", "failed to setup - quitting");
SendLogFile(-98);
Terminate(0);
}
ProcessLine("#include <iostream>", kTRUE);
ProcessLine("#include <_string>",kTRUE);
ProcessLine("#include <RtypesCint.h>", kTRUE);
ProcessLine("#define ROOT_Rtypes 0", kTRUE);
ProcessLine("#define ROOT_TError 0", kTRUE);
ProcessLine("#define ROOT_TGenericClassInfo 0", kTRUE);
const char *logon;
logon = gEnv->GetValue("Rint.Load", (char *)0);
if (logon) {
char *mac = gSystem->Which(TROOT::GetMacroPath(), logon, kReadPermission);
if (mac)
ProcessLine(Form(".L %s", logon), kTRUE);
delete [] mac;
}
ExecLogon();
gBenchmark = new TBenchmark();
gInterpreter->SaveContext();
gInterpreter->SaveGlobalsContext();
gSystem->AddSignalHandler(new TASInterruptHandler(this));
gSystem->AddFileHandler(new TASInputHandler(this, sock));
fIsValid = kTRUE;
BrowseDirectory(0);
SendLogFile();
}
Int_t TApplicationServer::Setup()
{
char str[512];
sprintf(str, "**** Remote session @ %s started ****", gSystem->HostName());
if (fSocket->Send(str) != 1+static_cast<Int_t>(strlen(str))) {
Error("Setup", "failed to send startup message");
return -1;
}
if (fSocket->Send(kRRemote_Protocol, kROOTD_PROTOCOL) != 2*sizeof(Int_t)) {
Error("Setup", "failed to send local protocol");
return -1;
}
TMessage msg(kMESS_ANY);
msg << TString(gSystem->HostName()) << fLogFilePath;
fSocket->Send(msg);
fWorkDir = gSystem->WorkingDirectory();
if (strlen(fUrl.GetFile()) > 0) {
fWorkDir = fUrl.GetFile();
char *workdir = gSystem->ExpandPathName(fWorkDir.Data());
fWorkDir = workdir;
delete [] workdir;
}
if (gSystem->AccessPathName(fWorkDir)) {
gSystem->mkdir(fWorkDir, kTRUE);
if (!gSystem->ChangeDirectory(fWorkDir)) {
SysError("Setup", "can not change to directory %s",
fWorkDir.Data());
}
} else {
if (!gSystem->ChangeDirectory(fWorkDir)) {
gSystem->Unlink(fWorkDir);
gSystem->mkdir(fWorkDir, kTRUE);
if (!gSystem->ChangeDirectory(fWorkDir)) {
SysError("Setup", "can not change to directory %s",
fWorkDir.Data());
}
}
}
#if 0 // G.Ganis May 11, 2007
if (fSocket->SetOption(kProcessGroup, (-1)*gSystem->GetPid()) != 0)
SysWarning("Setup", "failed to enable SIGURG generation on incoming OOB");
#endif
if (fSocket->SetOption(kNoDelay, 1) != 0) {}
if (fSocket->SetOption(kKeepAlive, 1) != 0) {}
gSystem->AddSignalHandler(new TASSigPipeHandler(this));
return 0;
}
TApplicationServer::~TApplicationServer()
{
fSentCanvases->SetOwner(kFALSE);
SafeDelete(fSentCanvases);
SafeDelete(fSocket);
close(fLogFileDes);
}
void TApplicationServer::GetOptions(Int_t *argc, char **argv)
{
if (*argc < 4) {
Fatal("GetOptions", "must be started with 4 arguments");
gSystem->Exit(1);
}
fProtocol = TString(argv[1]).Atoi();
fUrl.SetUrl(argv[2]);
gDebug = 0;
TString argdbg(argv[3]);
if (argdbg.BeginsWith("-d=")) {
argdbg.ReplaceAll("-d=","");
gDebug = argdbg.Atoi();
}
}
void TApplicationServer::Run(Bool_t retrn)
{
if (fIsValid) {
TApplication::Run(retrn);
} else {
Error("Run", "invalid instance: cannot Run()");
gSystem->Exit(1);
}
}
void TApplicationServer::HandleSocketInput()
{
TMessage *mess;
char str[2048];
Int_t what;
if (fSocket->Recv(mess) <= 0) {
Error("HandleSocketInput", "retrieving message from input socket");
Terminate(0);
return;
}
what = mess->What();
if (gDebug > 0)
Info("HandleSocketInput", "got message of type %d", what);
switch (what) {
case kMESS_CINT:
{ TASLogHandlerGuard hg(fLogFile, fSocket, "", fRealTimeLog);
mess->ReadString(str, sizeof(str));
if (gDebug > 1)
Info("HandleSocketInput:kMESS_CINT", "processing: %s...", str);
ProcessLine(str);
}
SendCanvases();
SendLogFile();
break;
case kMESS_STRING:
mess->ReadString(str, sizeof(str));
break;
case kMESS_OBJECT:
mess->ReadObject(mess->GetClass());
break;
case kMESS_ANY:
{
Int_t type;
(*mess) >> type;
switch (type) {
case kRRT_Reset:
mess->ReadString(str, sizeof(str));
Reset(str);
break;
case kRRT_CheckFile:
HandleCheckFile(mess);
break;
case kRRT_File:
mess->ReadString(str, sizeof(str));
{ Long_t size;
Int_t bin;
char name[1024];
sscanf(str, "%s %d %ld", name, &bin, &size);
ReceiveFile(name, bin ? kTRUE : kFALSE, size);
}
break;
case kRRT_Terminate:
Int_t status;
(*mess) >> status;
Terminate(status);
break;
default:
break;
}
}
SendLogFile();
break;
default:
Warning("HandleSocketInput","message type unknown (%d)", what);
SendLogFile();
break;
}
delete mess;
}
void TApplicationServer::HandleUrgentData()
{
char oob_byte;
Int_t n, nch, wasted = 0;
const Int_t kBufSize = 1024;
char waste[kBufSize];
TASLogHandlerGuard hg(fLogFile, fSocket, "", fRealTimeLog);
Info("HandleUrgentData", "handling oob...");
while ((n = fSocket->RecvRaw(&oob_byte, 1, kOob)) < 0) {
if (n == -2) {
fSocket->GetOption(kBytesToRead, nch);
if (nch == 0) {
gSystem->Sleep(1000);
continue;
}
if (nch > kBufSize) nch = kBufSize;
n = fSocket->RecvRaw(waste, nch);
if (n <= 0) {
Error("HandleUrgentData", "error receiving waste");
break;
}
wasted = 1;
} else {
Error("HandleUrgentData", "error receiving OOB (n = %d)",n);
return;
}
}
Info("HandleUrgentData", "got OOB byte: %d\n", oob_byte);
switch (oob_byte) {
case kRRI_Hard:
Info("HandleUrgentData", "*** Hard Interrupt");
while (1) {
Int_t atmark;
fSocket->GetOption(kAtMark, atmark);
if (atmark) {
n = fSocket->SendRaw(&oob_byte, 1, kOob);
if (n <= 0)
Error("HandleUrgentData", "error sending OOB");
break;
}
fSocket->GetOption(kBytesToRead, nch);
if (nch == 0) {
gSystem->Sleep(1000);
continue;
}
if (nch > kBufSize) nch = kBufSize;
n = fSocket->RecvRaw(waste, nch);
if (n <= 0) {
Error("HandleUrgentData", "error receiving waste (2)");
break;
}
}
SendLogFile();
break;
case kRRI_Soft:
Info("HandleUrgentData", "Soft Interrupt");
if (wasted) {
Error("HandleUrgentData", "soft interrupt flushed stream");
break;
}
Interrupt();
SendLogFile();
break;
case kRRI_Shutdown:
Info("HandleUrgentData", "Shutdown Interrupt");
Terminate(0);
break;
default:
Error("HandleUrgentData", "unexpected OOB byte");
break;
}
}
void TApplicationServer::HandleSigPipe()
{
TASLogHandlerGuard hg(fLogFile, fSocket, "", fRealTimeLog);
Info("HandleSigPipe", "client died");
Terminate(0);
}
void TApplicationServer::Reset(const char *dir)
{
gDirectory->cd(dir);
gROOT->Reset();
if (gDirectory != gROOT) {
gDirectory->Delete();
}
}
Int_t TApplicationServer::ReceiveFile(const char *file, Bool_t bin, Long64_t size)
{
if (size <= 0) return 0;
Int_t fd = open(file, O_CREAT | O_TRUNC | O_WRONLY, 0600);
if (fd < 0) {
SysError("ReceiveFile", "error opening file %s", file);
return -1;
}
const Int_t kMAXBUF = 16384;
char buf[kMAXBUF], cpy[kMAXBUF];
Int_t left, r;
Long64_t filesize = 0;
while (filesize < size) {
left = Int_t(size - filesize);
if (left > kMAXBUF)
left = kMAXBUF;
r = fSocket->RecvRaw(&buf, left);
if (r > 0) {
char *p = buf;
filesize += r;
while (r) {
Int_t w;
if (!bin) {
Int_t k = 0, i = 0, j = 0;
char *q;
while (i < r) {
if (p[i] == '\r') {
i++;
k++;
}
cpy[j++] = buf[i++];
}
q = cpy;
r -= k;
w = write(fd, q, r);
} else {
w = write(fd, p, r);
}
if (w < 0) {
SysError("ReceiveFile", "error writing to file %s", file);
close(fd);
return -1;
}
r -= w;
p += w;
}
} else if (r < 0) {
Error("ReceiveFile", "error during receiving file %s", file);
close(fd);
return -1;
}
}
close(fd);
chmod(file, 0644);
return 0;
}
void TApplicationServer::SendLogFile(Int_t status, Int_t start, Int_t end)
{
fflush(stdout);
off_t ltot=0, lnow=0;
Int_t left = -1;
Bool_t adhoc = kFALSE;
if (fLogFileDes > -1) {
ltot = lseek(fileno(stdout), (off_t) 0, SEEK_END);
lnow = lseek(fLogFileDes, (off_t) 0, SEEK_CUR);
if (start > -1) {
lseek(fLogFileDes, (off_t) start, SEEK_SET);
if (end <= start || end > ltot)
end = ltot;
left = (Int_t)(end - start);
if (end < ltot)
left++;
adhoc = kTRUE;
} else {
left = (Int_t)(ltot - lnow);
}
}
TMessage m(kMESS_ANY);
if (left > 0) {
m << (Int_t)kRRT_LogFile << left;
fSocket->Send(m);
const Int_t kMAXBUF = 32768;
char buf[kMAXBUF];
Int_t wanted = (left > kMAXBUF) ? kMAXBUF : left;
Int_t len;
do {
while ((len = read(fLogFileDes, buf, wanted)) < 0 &&
TSystem::GetErrno() == EINTR)
TSystem::ResetErrno();
if (len < 0) {
SysError("SendLogFile", "error reading log file");
break;
}
if (end == ltot && len == wanted)
buf[len-1] = '\n';
if (fSocket->SendRaw(buf, len) < 0) {
SysError("SendLogFile", "error sending log file");
break;
}
left -= len;
wanted = (left > kMAXBUF) ? kMAXBUF : left;
} while (len > 0 && left > 0);
}
if (adhoc)
lseek(fLogFileDes, lnow, SEEK_SET);
m.Reset();
m << (Int_t)kRRT_LogDone << status;
fSocket->Send(m);
}
Int_t TApplicationServer::SendCanvases()
{
Int_t nc = 0;
TMessage mess(kMESS_OBJECT);
TIter next(gROOT->GetListOfCanvases());
TObject *o = 0;
while ((o = next())) {
if (!fSentCanvases)
fSentCanvases = new TList;
Bool_t sentalready = kFALSE;
TObjLink *lnk = fSentCanvases->FirstLink();
while (lnk) {
TObject *sc = lnk->GetObject();
lnk = lnk->Next();
if ((sc->TestBit(kNotDeleted)) && sc == o)
sentalready = kTRUE;
}
if (!sentalready) {
if (gDebug > 0)
Info("SendCanvases","new canvas found: %p", o);
mess.Reset(kMESS_OBJECT);
mess.WriteObject(o);
fSocket->Send(mess);
nc++;
fSentCanvases->Add(o);
}
}
return nc;
}
Int_t TApplicationServer::BrowseDirectory(const char *dirname)
{
Int_t nc = 0;
TMessage mess(kMESS_OBJECT);
if (!fWorkingDir || !dirname || !*dirname) {
if (!fWorkingDir)
fWorkingDir = new TRemoteObject(fWorkDir, fWorkDir, "TSystemDirectory");
fWorkingDir->Browse();
mess.Reset(kMESS_OBJECT);
mess.WriteObject(fWorkingDir);
fSocket->Send(mess);
nc++;
}
else if (fWorkingDir) {
TRemoteObject dir(dirname, dirname, "TSystemDirectory");
TList *list = dir.Browse();
mess.Reset(kMESS_OBJECT);
mess.WriteObject(list);
fSocket->Send(mess);
nc++;
}
return nc;
}
Int_t TApplicationServer::BrowseFile(const char *fname)
{
Int_t nc = 0;
TList *list = new TList;
TMessage mess(kMESS_OBJECT);
if (!fname || !*fname) {
TIter next(gROOT->GetListOfFiles());
TNamed *fh = 0;
TRemoteObject *robj;
while ((fh = (TNamed *)next())) {
robj = new TRemoteObject(fh->GetName(), fh->GetTitle(), "TFile");
list->Add(robj);
}
if (list->GetEntries() > 0) {
mess.Reset(kMESS_OBJECT);
mess.WriteObject(list);
fSocket->Send(mess);
nc++;
}
}
else {
TDirectory *fh = (TDirectory *)gROOT->GetListOfFiles()->FindObject(fname);
if (fh) {
fh->cd();
TRemoteObject dir(fh->GetName(), fh->GetTitle(), "TFile");
TList *keylist = (TList *)gROOT->ProcessLine(Form("((TFile *)0x%lx)->GetListOfKeys();", fh));
TIter nextk(keylist);
TNamed *key = 0;
TRemoteObject *robj;
while ((key = (TNamed *)nextk())) {
robj = new TRemoteObject(key->GetName(), key->GetTitle(), "TKey");
const char *classname = (const char *)gROOT->ProcessLine(Form("((TKey *)0x%lx)->GetClassName();", key));
robj->SetKeyClassName(classname);
Bool_t isFolder = (Bool_t)gROOT->ProcessLine(Form("((TKey *)0x%lx)->IsFolder();", key));
robj->SetFolder(isFolder);
robj->SetRemoteAddress((Long_t) key);
list->Add(robj);
}
if (list->GetEntries() > 0) {
mess.Reset(kMESS_OBJECT);
mess.WriteObject(list);
fSocket->Send(mess);
nc++;
}
}
}
return nc;
}
Int_t TApplicationServer::BrowseKey(const char *keyname)
{
Int_t nc = 0;
TMessage mess(kMESS_OBJECT);
TNamed *obj = (TNamed *)gROOT->ProcessLine(Form("gFile->GetKey(\"%s\")->ReadObj();", keyname));
if (obj) {
mess.Reset(kMESS_OBJECT);
mess.WriteObject(obj);
fSocket->Send(mess);
nc++;
}
return nc;
}
void TApplicationServer::Terminate(Int_t status)
{
if (fLogFile) {
fclose(fLogFile);
if (gDebug <= 0)
gSystem->Unlink(fLogFilePath);
TString cleanup = fLogFilePath;
cleanup.ReplaceAll(".log", ".cleanup");
gSystem->Unlink(cleanup);
}
TIter next(gSystem->GetListOfFileHandlers());
TObject *fh = 0;
while ((fh = next())) {
TASInputHandler *ih = dynamic_cast<TASInputHandler *>(fh);
if (ih)
gSystem->RemoveFileHandler(ih);
}
gSystem->Exit(status);
}
void TApplicationServer::HandleCheckFile(TMessage *mess)
{
TString filenam;
TMD5 md5;
TMessage m(kMESS_ANY);
(*mess) >> filenam >> md5;
TMD5 *md5local = TMD5::FileChecksum(filenam);
if (md5local && md5 == (*md5local)) {
m << (Int_t) kRRT_CheckFile << (Bool_t) kTRUE;
fSocket->Send(m);
if (gDebug > 0)
Info("HandleCheckFile", "up-to-date version of %s available", filenam.Data());
} else {
m << (Int_t) kRRT_CheckFile << (Bool_t) kFALSE;
fSocket->Send(m);
if (gDebug > 0)
Info("HandleCheckFile", "file %s needs to be uploaded", filenam.Data());
}
delete md5local;
}
void TApplicationServer::ErrorHandler(Int_t level, Bool_t abort, const char *location,
const char *msg)
{
if (gErrorIgnoreLevel == kUnset) {
gErrorIgnoreLevel = 0;
if (gEnv) {
TString slevel = gEnv->GetValue("Root.ErrorIgnoreLevel", "Print");
if (!slevel.CompareTo("Print", TString::kIgnoreCase))
gErrorIgnoreLevel = kPrint;
else if (!slevel.CompareTo("Info", TString::kIgnoreCase))
gErrorIgnoreLevel = kInfo;
else if (!slevel.CompareTo("Warning", TString::kIgnoreCase))
gErrorIgnoreLevel = kWarning;
else if (!slevel.CompareTo("Error", TString::kIgnoreCase))
gErrorIgnoreLevel = kError;
else if (!slevel.CompareTo("Break", TString::kIgnoreCase))
gErrorIgnoreLevel = kBreak;
else if (!slevel.CompareTo("SysError", TString::kIgnoreCase))
gErrorIgnoreLevel = kSysError;
else if (!slevel.CompareTo("Fatal", TString::kIgnoreCase))
gErrorIgnoreLevel = kFatal;
}
}
if (level < gErrorIgnoreLevel)
return;
static TString syslogService;
if (syslogService.IsNull()) {
syslogService = "server";
gSystem->Openlog(syslogService, kLogPid | kLogCons, kLogLocal5);
}
const char *type = 0;
ELogLevel loglevel = kLogInfo;
if (level >= kPrint) {
loglevel = kLogInfo;
type = "Print";
}
if (level >= kInfo) {
loglevel = kLogInfo;
type = "Info";
}
if (level >= kWarning) {
loglevel = kLogWarning;
type = "Warning";
}
if (level >= kError) {
loglevel = kLogErr;
type = "Error";
}
if (level >= kBreak) {
loglevel = kLogErr;
type = "*** Break ***";
}
if (level >= kSysError) {
loglevel = kLogErr;
type = "SysError";
}
if (level >= kFatal) {
loglevel = kLogErr;
type = "Fatal";
}
TString node = "server";
TString buf;
if (!location || strlen(location) == 0 ||
(level >= kPrint && level < kInfo) ||
(level >= kBreak && level < kSysError)) {
fprintf(stderr, "%s on %s: %s\n", type, node.Data(), msg);
buf.Form("%s:%s:%s", node.Data(), type, msg);
} else {
fprintf(stderr, "%s in <%s> on %s: %s\n", type, location, node.Data(), msg);
buf.Form("%s:%s:<%s>:%s", node.Data(), type, location, msg);
}
fflush(stderr);
gSystem->Syslog(loglevel, buf);
if (abort) {
fprintf(stderr, "aborting\n");
fflush(stderr);
gSystem->StackTrace();
gSystem->Abort();
}
}
Long_t TApplicationServer::ProcessLine(const char *line, Bool_t, Int_t *)
{
if (!line || !*line) return 0;
if (!strncmp(line, ".L", 2) || !strncmp(line, ".U", 2) ||
!strncmp(line, ".X", 2) || !strncmp(line, ".x", 2)) {
TString aclicMode;
TString arguments;
TString io;
TString fname = gSystem->SplitAclicMode(line+3, aclicMode, arguments, io);
char *imp = gSystem->Which(TROOT::GetMacroPath(), fname, kReadPermission);
if (!imp) {
if (gSystem->AccessPathName(gSystem->WorkingDirectory(), kWritePermission)) {
Error("ProcessLine","no write permission in %s", gSystem->WorkingDirectory());
return 0;
}
if (gDebug > 0)
Info("ProcessLine", "macro %s not found in path %s: asking the client",
fname.Data(), TROOT::GetMacroPath());
TMessage m(kMESS_ANY);
m << (Int_t) kRRT_SendFile << TString(gSystem->BaseName(fname));
fSocket->Send(m);
Int_t type;
Bool_t filefollows = kTRUE;
while (filefollows) {
TMessage *rm = 0;
if (fSocket->Recv(rm) <= 0) {
Error("ProcessLine","ask-file: received empty message from client");
return 0;
}
if (rm->What() != kMESS_ANY) {
Error("ProcessLine","ask-file: wrong message received (what: %d)", rm->What());
return 0;
}
(*rm) >> type;
if (type != kRRT_SendFile) {
Error("ProcessLine","ask-file: wrong sub-type received (type: %d)", type);
return 0;
}
(*rm) >> filefollows;
if (filefollows) {
if (fSocket->Recv(rm) <= 0) {
Error("ProcessLine","file: received empty message from client");
return 0;
}
if (rm->What() != kMESS_ANY) {
Error("ProcessLine","file: wrong message received (what: %d)", rm->What());
return 0;
}
(*rm) >> type;
if (type != kRRT_File) {
Error("ProcessLine","file: wrong sub-type received (type: %d)", type);
return 0;
}
char str[2048];
rm->ReadString(str, sizeof(str));
Long_t size;
Int_t bin;
char name[1024];
sscanf(str, "%s %d %ld", name, &bin, &size);
ReceiveFile(name, bin ? kTRUE : kFALSE, size);
}
}
}
}
return TApplication::ProcessLine(line);
}
void TApplicationServer::ExecLogon()
{
if (NoLogOpt()) return;
TString name = ".rootlogon.C";
TString sname = "system";
sname += name;
#ifdef ROOTETCDIR
char *s = gSystem->ConcatFileName(ROOTETCDIR, sname);
#else
TString etc = gRootDir;
#ifdef WIN32
etc += "\\etc";
#else
etc += "/etc";
#endif
char *s = gSystem->ConcatFileName(etc, sname);
#endif
if (!gSystem->AccessPathName(s, kReadPermission)) {
ProcessFile(s);
}
delete [] s;
s = gSystem->ConcatFileName(gSystem->HomeDirectory(), name);
if (!gSystem->AccessPathName(s, kReadPermission)) {
ProcessFile(s);
}
delete [] s;
if (strcmp(gSystem->HomeDirectory(), gSystem->WorkingDirectory())) {
if (!gSystem->AccessPathName(name, kReadPermission))
ProcessFile(name);
}
const char *logon = gEnv->GetValue("Rint.Logon", (char*)0);
if (logon) {
char *mac = gSystem->Which(TROOT::GetMacroPath(), logon, kReadPermission);
if (mac)
ProcessFile(logon);
delete [] mac;
}
}
Last change: Wed Jun 25 08:34:42 2008
Last generated: 2008-06-25 08:34
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.