ROOT logo
//__________________________________________________[C++ CLASS IMPLEMENTATION]
//////////////////////////////////////////////////////////////////////////////
// Name:           c2lynx/src/TMrbC2Lynx.cxx
// Purpose:        MARaBOU client to connect to LynxOs/VME
// Description:    Implements class methods for a client to LynxOs/VME
// Keywords:
// Author:         R. Lutter
// Mailto:         <a href=mailto:rudi.lutter@physik.uni-muenchen.de>R. Lutter</a>
// Revision:       $Id: TMrbC2Lynx.cxx,v 1.17 2011-05-20 12:21:10 Marabou Exp $
// Date:           $Date: 2011-05-20 12:21:10 $
//////////////////////////////////////////////////////////////////////////////

namespace std {} using namespace std;

#include <cstdlib>
#include <time.h>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <fstream>

#include "Rtypes.h"
#include "TROOT.h"
#include "TArrayI.h"
#include "TSystem.h"
#include "TEnv.h"
#include "TObjString.h"

#include "TMrbNamedX.h"
#include "TMrbLofNamedX.h"
#include "TMrbLogger.h"
#include "TMrbSystem.h"

#include "TMrbC2Lynx.h"

#include "SetColor.h"

extern TMrbLogger * gMrbLog;

TMrbC2Lynx * gMrbC2Lynx = NULL;

static Char_t * gMsgBuffer = NULL; 			// common data storage for messages
static Int_t gBytesAllocated = 0;			// size of message storage

ClassImp(TMrbC2Lynx)

const SMrbNamedX kC2LLofServerLogs[] =
			{
				{TMrbC2Lynx::kC2LServerLogNone,	 	"none",		"No server output at all" 	},
				{TMrbC2Lynx::kC2LServerLogCout, 	"cout",		"Server output to cout/cerr" 	},
				{TMrbC2Lynx::kC2LServerLogXterm, 	"xterm",	"Server output to XTERM window"		},
				{0, 								NULL,			NULL						}
			};

TMrbC2Lynx::TMrbC2Lynx(const Char_t * HostName, const Char_t * Server, const Char_t * LogFile,
					Int_t Port, const Char_t * ServerLog, Bool_t ConnectFlag) : TNamed(HostName, "Marabou-Lynx connection") {
//__________________________________________________________________[C++ CTOR]
//////////////////////////////////////////////////////////////////////////////
// Name:           TMrbC2Lynx
// Purpose:        Connect to LynxOs
// Arguments:      Char_t * HostName      -- server host
//                 Char_t * Server        -- server path
//                 Char_t * LogFile       -- where to write log messages
//                 Int_t Port             -- tcp port
//                 Char_t * ServerLog     -- where to output server logs
//                 Bool_t ConnectFlag     -- try to establish connection
// Results:        --
// Description:    Class constructor
//////////////////////////////////////////////////////////////////////////////

	if (gMrbC2Lynx != NULL) {
		gMrbLog->Err()	<< "Connection to LynxOs already established" << endl;
		gMrbLog->Flush(this->ClassName());
		this->MakeZombie();
	} else {
		this->Reset();

		fLofServerLogs.SetName("Server output modes");
		fLofServerLogs.AddNamedX(kC2LLofServerLogs);

		fHost = HostName;
		fPort = Port;

		fNonBlocking = kFALSE;
		fSocket = NULL;

		fServerLog = fLofServerLogs.FindByName(ServerLog);
		if (fServerLog == NULL) {
			gMrbLog->Err()	<< "Illegal server output mode - " << ServerLog << endl;
			gMrbLog->Flush(this->ClassName());
			this->MakeZombie();
		}

		if (!this->IsZombie()) {
			if (Server == NULL || *Server == '\0') {
				TString lynxVersion = gEnv->GetValue("TMrbC2Lynx.LynxVersion", "");
				if (lynxVersion.IsNull()) lynxVersion = gEnv->GetValue("TMbsSetup.LynxVersion", "");
				if (lynxVersion.IsNull()) {
					gMrbLog->Err()	<< "Lynx version missing - set \"TMrbC2Lynx.LynxVersion\" properly" << endl;
					gMrbLog->Flush(this->ClassName());
					this->MakeZombie();
				} else {
					fServerPath = Form("$MARABOU/powerpc/bin/%s/mrbLynxOsSrv", lynxVersion.Data());
				}
			} else {
				fServerPath = Server;
			}
			if (!this->IsZombie()) {
				gSystem->ExpandPathName(fServerPath);
				fServerName = gSystem->BaseName(fServerPath.Data());
				fLogFile = (LogFile == NULL || *LogFile == '\0') ? Form("%s/c2lynx.log", gSystem->WorkingDirectory()) : LogFile;

				if (ConnectFlag) {
					if (this->Connect(kTRUE)) {
						gMrbC2Lynx = this;
						gROOT->Append(this);
					} else {
						this->MakeZombie();
					}
				}
			}
		}
	}
}

Bool_t TMrbC2Lynx::Connect(Bool_t WaitFlag) {
//________________________________________________________________[C++ METHOD]
//////////////////////////////////////////////////////////////////////////////
// Name:           TMrbC2Lynx::Connect
// Purpose:        Connect to server
// Arguments:      Bool_t WaitFlag  -- wait for connection to establish if kTRUE
// Results:        kTRUE/kFALSE
// Exceptions:
// Description:    (Re)Connects to server.
// Keywords:
//////////////////////////////////////////////////////////////////////////////

	if (this->IsConnected()) return(kTRUE);

	TString cpu, lynx;
	if (!this->CheckVersion(cpu, lynx, fHost.Data(), fServerPath.Data())) {
		gMrbLog->Err()	<< "Version mismatch - cpu=" << cpu << ", lynx=" << lynx << endl;
		gMrbLog->Flush(this->ClassName(), "Connect");
		return(kFALSE);
	}

	if (!gSystem->AccessPathName(fHost.Data()) || fHost[0] == '/') {
		gMrbLog->Err() << "Can't connect to server " << fHost << " (remove file with same name first!)" << endl;
		gMrbLog->Flush(this->ClassName(), "Connect");
		return kFALSE;
	}
	
	TSocket * s = new TSocket(fHost.Data(), fPort);
	Bool_t sockOk = s->IsValid();
	if (sockOk) {
		if (fVerboseMode || fDebugMode) {
			gMrbLog->Out()	<< "Connecting to server " << fHost << ":" << fPort
							<< " (progr " << fServerName << ")" << endl;
			gMrbLog->Flush(this->ClassName(), "Connect");
		}
		fSocket = s;
		gMrbC2Lynx = this;
		gROOT->Append(this);
		return(kTRUE);
	} else {
		if (fVerboseMode || fDebugMode) {
			gMrbLog->Out()	<< "Trying to connect to server " << fHost << ":" << fPort
							<< " (progr " << fServerName << ")" << endl;
			gMrbLog->Flush(this->ClassName(), "Connect");
		}
		delete s;
		TString cmd1, cmd2;
		if (this->LogXterm()) {
			cmd1 = "konsole -title ";
			cmd1 += fServerName;
			cmd1 += "@";
			cmd1 += fHost;
			cmd1 += " -e rsh ";
		} else {
			cmd1 = "rsh ";
		}
		cmd1 += fHost;
		cmd1 += " ";

		cmd2 = fServerPath;
		cmd2 += " ";
		cmd2 += fPort;
		cmd2 += " ";
		cmd2 += fLogFile;
		cmd2 += " ";
		cmd2 += (fNonBlocking ? 1 : 0);
		cmd2 += " ";
		cmd2 += (fVerboseMode ? 1 : 0);

		if (fDebugMode) {
			gMrbLog->Out()	<< "[Debug mode] Start manually @ " << fHost << " >> " << cmd2 << " <<" << endl;
			gMrbLog->Flush(this->ClassName(), "Connect");
		} else {
			cmd1 += cmd2;
			TMrbNamedX * sl = this->GetServerLog();
			if (sl) {
				switch (sl->GetIndex()) {
					case kC2LServerLogNone:		cmd1 += " 1>/dev/null 2>/dev/null"; break;
					case kC2LServerLogCout:		cmd1 += " 2>/dev/null"; break;
					case kC2LServerLogXterm:	break;
				}
			}
			cmd1 += " &";
			if (fVerboseMode) {
				gMrbLog->Out()	<< "Exec >> " << cmd1 << " <<" << endl;
				gMrbLog->Flush(this->ClassName());
			}
			gSystem->Exec(cmd1.Data());
		}

		if (!WaitFlag) return(kTRUE);

		Int_t wait = fDebugMode ? 100 : 10;
		for (Int_t i = 0; i < wait; i++) {
			sleep(1);
			if(this->WaitForConnection()) return(kTRUE);
		}
		gMrbLog->Err()	<< "Can't connect to server/port " << fHost << ":" << fPort << endl;
		gMrbLog->Flush(this->ClassName(), "Connect");
		fSocket = NULL;
		return(kFALSE);
	}
}

Bool_t TMrbC2Lynx::WaitForConnection() {
//________________________________________________________________[C++ METHOD]
//////////////////////////////////////////////////////////////////////////////
// Name:           TMrbC2Lynx::WaitForConnection
// Purpose:        Connect to server
// Arguments:      --
// Results:        kTRUE/kFALSE
// Exceptions:
// Description:    Wait for connection to establish.
// Keywords:
//////////////////////////////////////////////////////////////////////////////

	if (this->IsConnected()) return(kTRUE);
	TSocket * s = new TSocket(fHost.Data(), fPort);
	Bool_t sockOk = s->IsValid();
	if (sockOk) {
		fSocket = s;
		gMrbC2Lynx = this;
		gROOT->Append(this);
		return(kTRUE);
	}
	delete s;
	return(kFALSE);
}

void TMrbC2Lynx::Reset() {
//________________________________________________________________[C++ METHOD]
//////////////////////////////////////////////////////////////////////////////
// Name:           TMrbC2Lynx::Reset
// Purpose:        Reset internal data base
// Arguments:      --
// Results:        --
// Exceptions:
// Description:    Reset data base (protected method).
// Keywords:
//////////////////////////////////////////////////////////////////////////////

	if (gMrbLog == NULL) gMrbLog = new TMrbLogger("c2lynx.log");

	fVerboseMode = gEnv->GetValue("TMrbC2Lynx.VerboseMode", kFALSE);
	fDebugMode = gEnv->GetValue("TMrbC2Lynx.DebugMode", kFALSE);

	fNonBlocking = kFALSE;
	fServerLog = fLofServerLogs.FindByIndex(kC2LServerLogCout);

	fHost.Resize(0);								// host name
	fServerPath.Resize(0);
	fServerName.Resize(0);

	fPort = -1;
	fSocket = NULL;
}

Bool_t TMrbC2Lynx::SetServerLog(const Char_t * Output) {
//________________________________________________________________[C++ METHOD]
//////////////////////////////////////////////////////////////////////////////
// Name:           TMrbC2Lynx::SetServerLog
// Purpose:        Define output mode
// Arguments:      Char_t * Output   -- output mode
// Results:        kTRUE/kFALSE
// Exceptions:
// Description:    Defines output mode for server logs
// Keywords:
//////////////////////////////////////////////////////////////////////////////

	TMrbNamedX * sl = fLofServerLogs.FindByName(Output);
	if (sl == NULL) {
		gMrbLog->Err()	<< "Illegal output mode " << Output << endl;
		gMrbLog->Flush(this->ClassName(), "SetServerLog");
		return(kFALSE);
	} else {
		fServerLog = sl;
		return(kTRUE);
	}
}

Bool_t TMrbC2Lynx::SetServerLog(EC2LServerLog Output) {
//________________________________________________________________[C++ METHOD]
//////////////////////////////////////////////////////////////////////////////
// Name:           TMrbC2Lynx::SetServerLog
// Purpose:        Define output mode
// Arguments:      EC2LServerLog Output   -- output mode
// Results:        kTRUE/kFALSE
// Exceptions:
// Description:    Defines output mode for server logs
// Keywords:
//////////////////////////////////////////////////////////////////////////////

	TMrbNamedX * sl = fLofServerLogs.FindByIndex(Output);
	if (sl == NULL) {
		gMrbLog->Err()	<< "Illegal output mode " << setbase(16) << Output << setbase(10) << endl;
		gMrbLog->Flush(this->ClassName(), "SetServerLog");
		return(kFALSE);
	} else {
		fServerLog = sl;
		return(kTRUE);
	}
}

Bool_t TMrbC2Lynx::Send(M2L_MsgHdr * Hdr) {
//________________________________________________________________[C++ METHOD]
//////////////////////////////////////////////////////////////////////////////
// Name:           TMrbC2Lynx::Send
// Purpose:        Send a message
// Arguments:      M2L_MsgHdr * Hdr  -- (header of) message to be sent
// Results:        kTRUE/kFALSE
// Exceptions:
// Description:    Sends a message over internal socket.
// Keywords:
//////////////////////////////////////////////////////////////////////////////

	if (this->IsConnected()) {
		Int_t n = fSocket->SendRaw((void *) Hdr, Hdr->fLength);
		if (n <= 0) {
			gMrbLog->Err()	<< "Couldn't send message (code=" << n << ")" << endl;
			gMrbLog->Flush(this->ClassName(), "Send");
			return(kFALSE);
		}
		return(kTRUE);
	} else {
		gMrbLog->Err()	<< "Not connected to server" << endl;
		gMrbLog->Flush(this->ClassName(), "Send");
		return(kFALSE);
	}
}

Bool_t TMrbC2Lynx::Recv(M2L_MsgHdr * Hdr) {
//________________________________________________________________[C++ METHOD]
//////////////////////////////////////////////////////////////////////////////
// Name:           TMrbC2Lynx::Recv
// Purpose:        Receive a message
// Arguments:      M2L_MsgHdr * Hdr  -- (header of) message
// Results:        kTRUE/kFALSE
// Exceptions:
// Description:    Sends a message over internal socket.
// Keywords:
//////////////////////////////////////////////////////////////////////////////

	if (this->IsConnected()) {
		M2L_MsgHdr reqHdr;
		memcpy(&reqHdr, Hdr, sizeof(M2L_MsgHdr));
		if (reqHdr.fLength) {
			Int_t n = fSocket->RecvRaw((void *) Hdr, sizeof(M2L_MsgHdr));
			if (n != sizeof(M2L_MsgHdr)) {
				gMrbLog->Err()	<< "Couldn't receive header (error code=" << n << ")" << endl;
				gMrbLog->Flush(this->ClassName(), "Recv");
				return(kFALSE);
			}
			if (Hdr->fWhat >= kM2L_MESS_ACK_OK && Hdr->fWhat < kM2L_MESS_ACK_END) {
				M2L_Acknowledge ack;
				n = fSocket->RecvRaw((void *) ack.fText, Hdr->fLength - sizeof(M2L_MsgHdr));
				if (n <= 0) {
					gMrbLog->Err()	<< "Couldn't receive message (error code=" << n << ")" << endl;
					gMrbLog->Flush(this->ClassName(), "Recv");
					return(kFALSE);
				}
				switch (Hdr->fWhat) {
					case kM2L_MESS_ACK_OK:			return(kTRUE);
					case kM2L_MESS_ACK_MESSAGE: 	cout << "*-" << ack.fText << endl; break;
					case kM2L_MESS_ACK_WARNING: 	cerr << "%-" << ack.fText << endl; break;
					case kM2L_MESS_ACK_ERROR:		cerr << setred << "?-" << ack.fText << setblack << endl; break;
				}
				return(kFALSE);
			}
			n = fSocket->RecvRaw((void *)((Char_t *) Hdr + sizeof(M2L_MsgHdr)), Hdr->fLength - sizeof(M2L_MsgHdr));
			if (n <= 0) {
				gMrbLog->Err()	<< "Couldn't receive message (error code=" << n << ")" << endl;
				gMrbLog->Flush(this->ClassName(), "Recv");
				return(kFALSE);
			}
			return(kTRUE);
		} else {
			gMrbLog->Err()	<< "Requested message length is 0" << endl;
			gMrbLog->Flush(this->ClassName(), "Recv");
			return(kFALSE);
		}
	} else {
		gMrbLog->Err()	<< "Not connected to server" << endl;
		gMrbLog->Flush(this->ClassName(), "Recv");
		return(kFALSE);
	}
}

void TMrbC2Lynx::Bye() {
//________________________________________________________________[C++ METHOD]
//////////////////////////////////////////////////////////////////////////////
// Name:           TMrbC2Lynx::Bye
// Purpose:        Terminate session
// Arguments:      --
// Results:        --
// Exceptions:
// Description:    Sends a bye message to server and terminates connection.
// Keywords:
//////////////////////////////////////////////////////////////////////////////

	if (this->IsConnected()) {
		M2L_MsgHdr bye;
		bye.fWhat = kM2L_MESS_BYE;
		bye.fLength = sizeof(M2L_MsgHdr);
		this->Send(&bye);
		M2L_Acknowledge a;
		this->InitMessage((M2L_MsgHdr *) &a, sizeof(M2L_Acknowledge), kM2L_MESS_BYE);
		if (this->Recv((M2L_MsgHdr *) &a)) {
			fSocket->Close();
			fSocket = NULL;
		}
	} else {
		gMrbLog->Err()	<< "Not connected to server" << endl;
		gMrbLog->Flush(this->ClassName(), "Bye");
	}
	return;
}

void TMrbC2Lynx::InitMessage(M2L_MsgHdr * Hdr, Int_t Length, UInt_t What) {
//________________________________________________________________[C++ METHOD]
//////////////////////////////////////////////////////////////////////////////
// Name:           TMrbC2Lynx::InitMessage
// Purpose:        Initialize message
// Arguments:      M2L_MsgHdr * Hdr    -- ptr to message (header)
//                 Int_t Length        -- message length
//                 UInt_t What         -- message type
// Results:        --
// Exceptions:
// Description:    Clears message data and fills header
// Keywords:
//////////////////////////////////////////////////////////////////////////////

	memset((Char_t *) Hdr, 0, Length);
	Hdr->fLength = Length;
	Hdr->fWhat = What;
}

M2L_MsgHdr * TMrbC2Lynx::AllocMessage(Int_t Length, Int_t Wc, UInt_t What) {
//________________________________________________________________[C++ METHOD]
//////////////////////////////////////////////////////////////////////////////
// Name:           TMrbC2Lynx::AllocMessage
// Purpose:        Allocate message
// Arguments:      Int_t Length        -- message length
//                 Int_t Wc            -- length of data (words)
//                 UInt_t What         -- message type
// Results:        M2L_MsgHdr * Hdr    -- ptr to message (header)
// Exceptions:
// Description:    Allocates message on heap
// Keywords:
//////////////////////////////////////////////////////////////////////////////

	Int_t lengthNeeded = Length + (Wc - 1) * sizeof(Int_t);
	if (gBytesAllocated < lengthNeeded) {
		gMsgBuffer = (Char_t *) calloc(1, lengthNeeded);
		gBytesAllocated = lengthNeeded;
	}
	memset(gMsgBuffer, 0, gBytesAllocated);
	this->InitMessage((M2L_MsgHdr *) gMsgBuffer, lengthNeeded, What);
	return((M2L_MsgHdr *) gMsgBuffer);
}

Bool_t TMrbC2Lynx::CheckAccessToLynxOs(const Char_t * Host, const Char_t * Path) {
//________________________________________________________________[C++ METHOD]
//////////////////////////////////////////////////////////////////////////////
// Name:           TMrbC2Lynx::CheckAccessToLynxOs
// Purpose:        Check access to file
// Arguments:      Char_t * Host        -- name of ppc host
//                 Char_t * Path        -- path to lynxOs server
// Results:        kTRUE/kFALSE
// Exceptions:
// Description:    Checks if path can be seen from lynxOs
// Keywords:
//////////////////////////////////////////////////////////////////////////////

	TString host = Host;
	TString path = Path;

	TString cmd = Form("rsh %s -e pwd 2>&1", host.Data());
	FILE * rsh = gSystem->OpenPipe(cmd.Data(), "r");
	if (!rsh) {
		gMrbLog->Err()	<< "Can't exec command - \"" << cmd << "\"" << endl;
		gMrbLog->Flush(this->ClassName(), "CheckAccessToLynxOs");
		return(kFALSE);
	}

	char line[512];
	fgets(line, 512, rsh);
	TString str = line;
	if (str.IsNull() || str.Contains("No route")) {
		gMrbLog->Err()	<< "Can't access host - " << host << endl;
		gMrbLog->Flush(this->ClassName(), "CheckAccessToLynxOs");
		return(kFALSE);
	}

	cmd = Form("rsh %s -e \'echo @X@%cls %s%c@X@\'", host.Data(), '\`', path.Data(), '\`');
	FILE * ls = gSystem->OpenPipe(cmd.Data(), "r");
	if (!ls) {
		gMrbLog->Err()	<< "Can't exec command - \"" << cmd << "\"" << endl;
		gMrbLog->Flush(this->ClassName(), "CheckAccessToLynxOs");
		return(kFALSE);
	}

	fgets(line, 512, ls);
	str = line;
	if (str.Contains("@X@@X@") || !str.Contains(Form("@X@%s", path.Data()))) {
		gMrbLog->Err()	<< "Can't access file from LynxOs host - \"" << host << ":" << path << "\"" << endl;
		gMrbLog->Flush(this->ClassName(), "CheckAccessToLynxOs");
		return(kFALSE);
	}
	return(kTRUE);
}

Bool_t TMrbC2Lynx::CheckVersion(TString & Cpu, TString & Lynx, const Char_t * Host, const Char_t * Path) {
//________________________________________________________________[C++ METHOD]
//////////////////////////////////////////////////////////////////////////////
// Name:           TMrbC2Lynx::CheckVersion
// Purpose:        Check server version
// Arguments:      Char_t * Host        -- name of ppc host
//                 Char_t * Path        -- path to lynxOs server
// Results:        kTRUE / kFALSE
//                 TString & Cpu        -- cpu version
//                 TString & Lynx       -- lynx version
// Exceptions:
// Description:    Checks file on server machine for occurrence of "@#@" strings:
//                 @#@CPU=RIOn
//                 @#@LynxOs=n.n
// Keywords:
//////////////////////////////////////////////////////////////////////////////

	Cpu = "n.a";
	Lynx = "n.a";

	TString host = Host;
	if (host.IsNull()) host = fHost;

	TString serverPath = Path;
	if (serverPath.IsNull()) serverPath = fServerPath;

	if (!this->CheckAccessToLynxOs(host.Data(), serverPath.Data())) return(kFALSE);

	TString cmd = Form("rsh %s -e strings %s | grep @#@", host.Data(), serverPath.Data());
	FILE * grep = gSystem->OpenPipe(cmd.Data(), "r");
	if (!grep) {
		gMrbLog->Err()	<< "Can't exec grep command - \"" << cmd << "\"" << endl;
		gMrbLog->Flush(this->ClassName(), "CheckVersion");
		return(kFALSE);
	}

	Char_t buf[128];
	while (fgets(buf, 128, grep)) {
		TString str = buf;
		str.Resize(str.Length() - 1);
		if (str.Contains("@#@")) {
			Int_t x = str.Index("CPU=", 0);
			if (x > 0) {
				Cpu = str(x + 4, 10);
				continue;
			}
			x = str.Index("LynxOs=", 0);
			if (x > 0) {
				Lynx = str(x + 7, 10);
				continue;
			}
		}
	}
	fclose(grep);
	return(Cpu.CompareTo("n.a") != 0 && Lynx.CompareTo("n.a") != 0);
}
 TMrbC2Lynx.cxx:1
 TMrbC2Lynx.cxx:2
 TMrbC2Lynx.cxx:3
 TMrbC2Lynx.cxx:4
 TMrbC2Lynx.cxx:5
 TMrbC2Lynx.cxx:6
 TMrbC2Lynx.cxx:7
 TMrbC2Lynx.cxx:8
 TMrbC2Lynx.cxx:9
 TMrbC2Lynx.cxx:10
 TMrbC2Lynx.cxx:11
 TMrbC2Lynx.cxx:12
 TMrbC2Lynx.cxx:13
 TMrbC2Lynx.cxx:14
 TMrbC2Lynx.cxx:15
 TMrbC2Lynx.cxx:16
 TMrbC2Lynx.cxx:17
 TMrbC2Lynx.cxx:18
 TMrbC2Lynx.cxx:19
 TMrbC2Lynx.cxx:20
 TMrbC2Lynx.cxx:21
 TMrbC2Lynx.cxx:22
 TMrbC2Lynx.cxx:23
 TMrbC2Lynx.cxx:24
 TMrbC2Lynx.cxx:25
 TMrbC2Lynx.cxx:26
 TMrbC2Lynx.cxx:27
 TMrbC2Lynx.cxx:28
 TMrbC2Lynx.cxx:29
 TMrbC2Lynx.cxx:30
 TMrbC2Lynx.cxx:31
 TMrbC2Lynx.cxx:32
 TMrbC2Lynx.cxx:33
 TMrbC2Lynx.cxx:34
 TMrbC2Lynx.cxx:35
 TMrbC2Lynx.cxx:36
 TMrbC2Lynx.cxx:37
 TMrbC2Lynx.cxx:38
 TMrbC2Lynx.cxx:39
 TMrbC2Lynx.cxx:40
 TMrbC2Lynx.cxx:41
 TMrbC2Lynx.cxx:42
 TMrbC2Lynx.cxx:43
 TMrbC2Lynx.cxx:44
 TMrbC2Lynx.cxx:45
 TMrbC2Lynx.cxx:46
 TMrbC2Lynx.cxx:47
 TMrbC2Lynx.cxx:48
 TMrbC2Lynx.cxx:49
 TMrbC2Lynx.cxx:50
 TMrbC2Lynx.cxx:51
 TMrbC2Lynx.cxx:52
 TMrbC2Lynx.cxx:53
 TMrbC2Lynx.cxx:54
 TMrbC2Lynx.cxx:55
 TMrbC2Lynx.cxx:56
 TMrbC2Lynx.cxx:57
 TMrbC2Lynx.cxx:58
 TMrbC2Lynx.cxx:59
 TMrbC2Lynx.cxx:60
 TMrbC2Lynx.cxx:61
 TMrbC2Lynx.cxx:62
 TMrbC2Lynx.cxx:63
 TMrbC2Lynx.cxx:64
 TMrbC2Lynx.cxx:65
 TMrbC2Lynx.cxx:66
 TMrbC2Lynx.cxx:67
 TMrbC2Lynx.cxx:68
 TMrbC2Lynx.cxx:69
 TMrbC2Lynx.cxx:70
 TMrbC2Lynx.cxx:71
 TMrbC2Lynx.cxx:72
 TMrbC2Lynx.cxx:73
 TMrbC2Lynx.cxx:74
 TMrbC2Lynx.cxx:75
 TMrbC2Lynx.cxx:76
 TMrbC2Lynx.cxx:77
 TMrbC2Lynx.cxx:78
 TMrbC2Lynx.cxx:79
 TMrbC2Lynx.cxx:80
 TMrbC2Lynx.cxx:81
 TMrbC2Lynx.cxx:82
 TMrbC2Lynx.cxx:83
 TMrbC2Lynx.cxx:84
 TMrbC2Lynx.cxx:85
 TMrbC2Lynx.cxx:86
 TMrbC2Lynx.cxx:87
 TMrbC2Lynx.cxx:88
 TMrbC2Lynx.cxx:89
 TMrbC2Lynx.cxx:90
 TMrbC2Lynx.cxx:91
 TMrbC2Lynx.cxx:92
 TMrbC2Lynx.cxx:93
 TMrbC2Lynx.cxx:94
 TMrbC2Lynx.cxx:95
 TMrbC2Lynx.cxx:96
 TMrbC2Lynx.cxx:97
 TMrbC2Lynx.cxx:98
 TMrbC2Lynx.cxx:99
 TMrbC2Lynx.cxx:100
 TMrbC2Lynx.cxx:101
 TMrbC2Lynx.cxx:102
 TMrbC2Lynx.cxx:103
 TMrbC2Lynx.cxx:104
 TMrbC2Lynx.cxx:105
 TMrbC2Lynx.cxx:106
 TMrbC2Lynx.cxx:107
 TMrbC2Lynx.cxx:108
 TMrbC2Lynx.cxx:109
 TMrbC2Lynx.cxx:110
 TMrbC2Lynx.cxx:111
 TMrbC2Lynx.cxx:112
 TMrbC2Lynx.cxx:113
 TMrbC2Lynx.cxx:114
 TMrbC2Lynx.cxx:115
 TMrbC2Lynx.cxx:116
 TMrbC2Lynx.cxx:117
 TMrbC2Lynx.cxx:118
 TMrbC2Lynx.cxx:119
 TMrbC2Lynx.cxx:120
 TMrbC2Lynx.cxx:121
 TMrbC2Lynx.cxx:122
 TMrbC2Lynx.cxx:123
 TMrbC2Lynx.cxx:124
 TMrbC2Lynx.cxx:125
 TMrbC2Lynx.cxx:126
 TMrbC2Lynx.cxx:127
 TMrbC2Lynx.cxx:128
 TMrbC2Lynx.cxx:129
 TMrbC2Lynx.cxx:130
 TMrbC2Lynx.cxx:131
 TMrbC2Lynx.cxx:132
 TMrbC2Lynx.cxx:133
 TMrbC2Lynx.cxx:134
 TMrbC2Lynx.cxx:135
 TMrbC2Lynx.cxx:136
 TMrbC2Lynx.cxx:137
 TMrbC2Lynx.cxx:138
 TMrbC2Lynx.cxx:139
 TMrbC2Lynx.cxx:140
 TMrbC2Lynx.cxx:141
 TMrbC2Lynx.cxx:142
 TMrbC2Lynx.cxx:143
 TMrbC2Lynx.cxx:144
 TMrbC2Lynx.cxx:145
 TMrbC2Lynx.cxx:146
 TMrbC2Lynx.cxx:147
 TMrbC2Lynx.cxx:148
 TMrbC2Lynx.cxx:149
 TMrbC2Lynx.cxx:150
 TMrbC2Lynx.cxx:151
 TMrbC2Lynx.cxx:152
 TMrbC2Lynx.cxx:153
 TMrbC2Lynx.cxx:154
 TMrbC2Lynx.cxx:155
 TMrbC2Lynx.cxx:156
 TMrbC2Lynx.cxx:157
 TMrbC2Lynx.cxx:158
 TMrbC2Lynx.cxx:159
 TMrbC2Lynx.cxx:160
 TMrbC2Lynx.cxx:161
 TMrbC2Lynx.cxx:162
 TMrbC2Lynx.cxx:163
 TMrbC2Lynx.cxx:164
 TMrbC2Lynx.cxx:165
 TMrbC2Lynx.cxx:166
 TMrbC2Lynx.cxx:167
 TMrbC2Lynx.cxx:168
 TMrbC2Lynx.cxx:169
 TMrbC2Lynx.cxx:170
 TMrbC2Lynx.cxx:171
 TMrbC2Lynx.cxx:172
 TMrbC2Lynx.cxx:173
 TMrbC2Lynx.cxx:174
 TMrbC2Lynx.cxx:175
 TMrbC2Lynx.cxx:176
 TMrbC2Lynx.cxx:177
 TMrbC2Lynx.cxx:178
 TMrbC2Lynx.cxx:179
 TMrbC2Lynx.cxx:180
 TMrbC2Lynx.cxx:181
 TMrbC2Lynx.cxx:182
 TMrbC2Lynx.cxx:183
 TMrbC2Lynx.cxx:184
 TMrbC2Lynx.cxx:185
 TMrbC2Lynx.cxx:186
 TMrbC2Lynx.cxx:187
 TMrbC2Lynx.cxx:188
 TMrbC2Lynx.cxx:189
 TMrbC2Lynx.cxx:190
 TMrbC2Lynx.cxx:191
 TMrbC2Lynx.cxx:192
 TMrbC2Lynx.cxx:193
 TMrbC2Lynx.cxx:194
 TMrbC2Lynx.cxx:195
 TMrbC2Lynx.cxx:196
 TMrbC2Lynx.cxx:197
 TMrbC2Lynx.cxx:198
 TMrbC2Lynx.cxx:199
 TMrbC2Lynx.cxx:200
 TMrbC2Lynx.cxx:201
 TMrbC2Lynx.cxx:202
 TMrbC2Lynx.cxx:203
 TMrbC2Lynx.cxx:204
 TMrbC2Lynx.cxx:205
 TMrbC2Lynx.cxx:206
 TMrbC2Lynx.cxx:207
 TMrbC2Lynx.cxx:208
 TMrbC2Lynx.cxx:209
 TMrbC2Lynx.cxx:210
 TMrbC2Lynx.cxx:211
 TMrbC2Lynx.cxx:212
 TMrbC2Lynx.cxx:213
 TMrbC2Lynx.cxx:214
 TMrbC2Lynx.cxx:215
 TMrbC2Lynx.cxx:216
 TMrbC2Lynx.cxx:217
 TMrbC2Lynx.cxx:218
 TMrbC2Lynx.cxx:219
 TMrbC2Lynx.cxx:220
 TMrbC2Lynx.cxx:221
 TMrbC2Lynx.cxx:222
 TMrbC2Lynx.cxx:223
 TMrbC2Lynx.cxx:224
 TMrbC2Lynx.cxx:225
 TMrbC2Lynx.cxx:226
 TMrbC2Lynx.cxx:227
 TMrbC2Lynx.cxx:228
 TMrbC2Lynx.cxx:229
 TMrbC2Lynx.cxx:230
 TMrbC2Lynx.cxx:231
 TMrbC2Lynx.cxx:232
 TMrbC2Lynx.cxx:233
 TMrbC2Lynx.cxx:234
 TMrbC2Lynx.cxx:235
 TMrbC2Lynx.cxx:236
 TMrbC2Lynx.cxx:237
 TMrbC2Lynx.cxx:238
 TMrbC2Lynx.cxx:239
 TMrbC2Lynx.cxx:240
 TMrbC2Lynx.cxx:241
 TMrbC2Lynx.cxx:242
 TMrbC2Lynx.cxx:243
 TMrbC2Lynx.cxx:244
 TMrbC2Lynx.cxx:245
 TMrbC2Lynx.cxx:246
 TMrbC2Lynx.cxx:247
 TMrbC2Lynx.cxx:248
 TMrbC2Lynx.cxx:249
 TMrbC2Lynx.cxx:250
 TMrbC2Lynx.cxx:251
 TMrbC2Lynx.cxx:252
 TMrbC2Lynx.cxx:253
 TMrbC2Lynx.cxx:254
 TMrbC2Lynx.cxx:255
 TMrbC2Lynx.cxx:256
 TMrbC2Lynx.cxx:257
 TMrbC2Lynx.cxx:258
 TMrbC2Lynx.cxx:259
 TMrbC2Lynx.cxx:260
 TMrbC2Lynx.cxx:261
 TMrbC2Lynx.cxx:262
 TMrbC2Lynx.cxx:263
 TMrbC2Lynx.cxx:264
 TMrbC2Lynx.cxx:265
 TMrbC2Lynx.cxx:266
 TMrbC2Lynx.cxx:267
 TMrbC2Lynx.cxx:268
 TMrbC2Lynx.cxx:269
 TMrbC2Lynx.cxx:270
 TMrbC2Lynx.cxx:271
 TMrbC2Lynx.cxx:272
 TMrbC2Lynx.cxx:273
 TMrbC2Lynx.cxx:274
 TMrbC2Lynx.cxx:275
 TMrbC2Lynx.cxx:276
 TMrbC2Lynx.cxx:277
 TMrbC2Lynx.cxx:278
 TMrbC2Lynx.cxx:279
 TMrbC2Lynx.cxx:280
 TMrbC2Lynx.cxx:281
 TMrbC2Lynx.cxx:282
 TMrbC2Lynx.cxx:283
 TMrbC2Lynx.cxx:284
 TMrbC2Lynx.cxx:285
 TMrbC2Lynx.cxx:286
 TMrbC2Lynx.cxx:287
 TMrbC2Lynx.cxx:288
 TMrbC2Lynx.cxx:289
 TMrbC2Lynx.cxx:290
 TMrbC2Lynx.cxx:291
 TMrbC2Lynx.cxx:292
 TMrbC2Lynx.cxx:293
 TMrbC2Lynx.cxx:294
 TMrbC2Lynx.cxx:295
 TMrbC2Lynx.cxx:296
 TMrbC2Lynx.cxx:297
 TMrbC2Lynx.cxx:298
 TMrbC2Lynx.cxx:299
 TMrbC2Lynx.cxx:300
 TMrbC2Lynx.cxx:301
 TMrbC2Lynx.cxx:302
 TMrbC2Lynx.cxx:303
 TMrbC2Lynx.cxx:304
 TMrbC2Lynx.cxx:305
 TMrbC2Lynx.cxx:306
 TMrbC2Lynx.cxx:307
 TMrbC2Lynx.cxx:308
 TMrbC2Lynx.cxx:309
 TMrbC2Lynx.cxx:310
 TMrbC2Lynx.cxx:311
 TMrbC2Lynx.cxx:312
 TMrbC2Lynx.cxx:313
 TMrbC2Lynx.cxx:314
 TMrbC2Lynx.cxx:315
 TMrbC2Lynx.cxx:316
 TMrbC2Lynx.cxx:317
 TMrbC2Lynx.cxx:318
 TMrbC2Lynx.cxx:319
 TMrbC2Lynx.cxx:320
 TMrbC2Lynx.cxx:321
 TMrbC2Lynx.cxx:322
 TMrbC2Lynx.cxx:323
 TMrbC2Lynx.cxx:324
 TMrbC2Lynx.cxx:325
 TMrbC2Lynx.cxx:326
 TMrbC2Lynx.cxx:327
 TMrbC2Lynx.cxx:328
 TMrbC2Lynx.cxx:329
 TMrbC2Lynx.cxx:330
 TMrbC2Lynx.cxx:331
 TMrbC2Lynx.cxx:332
 TMrbC2Lynx.cxx:333
 TMrbC2Lynx.cxx:334
 TMrbC2Lynx.cxx:335
 TMrbC2Lynx.cxx:336
 TMrbC2Lynx.cxx:337
 TMrbC2Lynx.cxx:338
 TMrbC2Lynx.cxx:339
 TMrbC2Lynx.cxx:340
 TMrbC2Lynx.cxx:341
 TMrbC2Lynx.cxx:342
 TMrbC2Lynx.cxx:343
 TMrbC2Lynx.cxx:344
 TMrbC2Lynx.cxx:345
 TMrbC2Lynx.cxx:346
 TMrbC2Lynx.cxx:347
 TMrbC2Lynx.cxx:348
 TMrbC2Lynx.cxx:349
 TMrbC2Lynx.cxx:350
 TMrbC2Lynx.cxx:351
 TMrbC2Lynx.cxx:352
 TMrbC2Lynx.cxx:353
 TMrbC2Lynx.cxx:354
 TMrbC2Lynx.cxx:355
 TMrbC2Lynx.cxx:356
 TMrbC2Lynx.cxx:357
 TMrbC2Lynx.cxx:358
 TMrbC2Lynx.cxx:359
 TMrbC2Lynx.cxx:360
 TMrbC2Lynx.cxx:361
 TMrbC2Lynx.cxx:362
 TMrbC2Lynx.cxx:363
 TMrbC2Lynx.cxx:364
 TMrbC2Lynx.cxx:365
 TMrbC2Lynx.cxx:366
 TMrbC2Lynx.cxx:367
 TMrbC2Lynx.cxx:368
 TMrbC2Lynx.cxx:369
 TMrbC2Lynx.cxx:370
 TMrbC2Lynx.cxx:371
 TMrbC2Lynx.cxx:372
 TMrbC2Lynx.cxx:373
 TMrbC2Lynx.cxx:374
 TMrbC2Lynx.cxx:375
 TMrbC2Lynx.cxx:376
 TMrbC2Lynx.cxx:377
 TMrbC2Lynx.cxx:378
 TMrbC2Lynx.cxx:379
 TMrbC2Lynx.cxx:380
 TMrbC2Lynx.cxx:381
 TMrbC2Lynx.cxx:382
 TMrbC2Lynx.cxx:383
 TMrbC2Lynx.cxx:384
 TMrbC2Lynx.cxx:385
 TMrbC2Lynx.cxx:386
 TMrbC2Lynx.cxx:387
 TMrbC2Lynx.cxx:388
 TMrbC2Lynx.cxx:389
 TMrbC2Lynx.cxx:390
 TMrbC2Lynx.cxx:391
 TMrbC2Lynx.cxx:392
 TMrbC2Lynx.cxx:393
 TMrbC2Lynx.cxx:394
 TMrbC2Lynx.cxx:395
 TMrbC2Lynx.cxx:396
 TMrbC2Lynx.cxx:397
 TMrbC2Lynx.cxx:398
 TMrbC2Lynx.cxx:399
 TMrbC2Lynx.cxx:400
 TMrbC2Lynx.cxx:401
 TMrbC2Lynx.cxx:402
 TMrbC2Lynx.cxx:403
 TMrbC2Lynx.cxx:404
 TMrbC2Lynx.cxx:405
 TMrbC2Lynx.cxx:406
 TMrbC2Lynx.cxx:407
 TMrbC2Lynx.cxx:408
 TMrbC2Lynx.cxx:409
 TMrbC2Lynx.cxx:410
 TMrbC2Lynx.cxx:411
 TMrbC2Lynx.cxx:412
 TMrbC2Lynx.cxx:413
 TMrbC2Lynx.cxx:414
 TMrbC2Lynx.cxx:415
 TMrbC2Lynx.cxx:416
 TMrbC2Lynx.cxx:417
 TMrbC2Lynx.cxx:418
 TMrbC2Lynx.cxx:419
 TMrbC2Lynx.cxx:420
 TMrbC2Lynx.cxx:421
 TMrbC2Lynx.cxx:422
 TMrbC2Lynx.cxx:423
 TMrbC2Lynx.cxx:424
 TMrbC2Lynx.cxx:425
 TMrbC2Lynx.cxx:426
 TMrbC2Lynx.cxx:427
 TMrbC2Lynx.cxx:428
 TMrbC2Lynx.cxx:429
 TMrbC2Lynx.cxx:430
 TMrbC2Lynx.cxx:431
 TMrbC2Lynx.cxx:432
 TMrbC2Lynx.cxx:433
 TMrbC2Lynx.cxx:434
 TMrbC2Lynx.cxx:435
 TMrbC2Lynx.cxx:436
 TMrbC2Lynx.cxx:437
 TMrbC2Lynx.cxx:438
 TMrbC2Lynx.cxx:439
 TMrbC2Lynx.cxx:440
 TMrbC2Lynx.cxx:441
 TMrbC2Lynx.cxx:442
 TMrbC2Lynx.cxx:443
 TMrbC2Lynx.cxx:444
 TMrbC2Lynx.cxx:445
 TMrbC2Lynx.cxx:446
 TMrbC2Lynx.cxx:447
 TMrbC2Lynx.cxx:448
 TMrbC2Lynx.cxx:449
 TMrbC2Lynx.cxx:450
 TMrbC2Lynx.cxx:451
 TMrbC2Lynx.cxx:452
 TMrbC2Lynx.cxx:453
 TMrbC2Lynx.cxx:454
 TMrbC2Lynx.cxx:455
 TMrbC2Lynx.cxx:456
 TMrbC2Lynx.cxx:457
 TMrbC2Lynx.cxx:458
 TMrbC2Lynx.cxx:459
 TMrbC2Lynx.cxx:460
 TMrbC2Lynx.cxx:461
 TMrbC2Lynx.cxx:462
 TMrbC2Lynx.cxx:463
 TMrbC2Lynx.cxx:464
 TMrbC2Lynx.cxx:465
 TMrbC2Lynx.cxx:466
 TMrbC2Lynx.cxx:467
 TMrbC2Lynx.cxx:468
 TMrbC2Lynx.cxx:469
 TMrbC2Lynx.cxx:470
 TMrbC2Lynx.cxx:471
 TMrbC2Lynx.cxx:472
 TMrbC2Lynx.cxx:473
 TMrbC2Lynx.cxx:474
 TMrbC2Lynx.cxx:475
 TMrbC2Lynx.cxx:476
 TMrbC2Lynx.cxx:477
 TMrbC2Lynx.cxx:478
 TMrbC2Lynx.cxx:479
 TMrbC2Lynx.cxx:480
 TMrbC2Lynx.cxx:481
 TMrbC2Lynx.cxx:482
 TMrbC2Lynx.cxx:483
 TMrbC2Lynx.cxx:484
 TMrbC2Lynx.cxx:485
 TMrbC2Lynx.cxx:486
 TMrbC2Lynx.cxx:487
 TMrbC2Lynx.cxx:488
 TMrbC2Lynx.cxx:489
 TMrbC2Lynx.cxx:490
 TMrbC2Lynx.cxx:491
 TMrbC2Lynx.cxx:492
 TMrbC2Lynx.cxx:493
 TMrbC2Lynx.cxx:494
 TMrbC2Lynx.cxx:495
 TMrbC2Lynx.cxx:496
 TMrbC2Lynx.cxx:497
 TMrbC2Lynx.cxx:498
 TMrbC2Lynx.cxx:499
 TMrbC2Lynx.cxx:500
 TMrbC2Lynx.cxx:501
 TMrbC2Lynx.cxx:502
 TMrbC2Lynx.cxx:503
 TMrbC2Lynx.cxx:504
 TMrbC2Lynx.cxx:505
 TMrbC2Lynx.cxx:506
 TMrbC2Lynx.cxx:507
 TMrbC2Lynx.cxx:508
 TMrbC2Lynx.cxx:509
 TMrbC2Lynx.cxx:510
 TMrbC2Lynx.cxx:511
 TMrbC2Lynx.cxx:512
 TMrbC2Lynx.cxx:513
 TMrbC2Lynx.cxx:514
 TMrbC2Lynx.cxx:515
 TMrbC2Lynx.cxx:516
 TMrbC2Lynx.cxx:517
 TMrbC2Lynx.cxx:518
 TMrbC2Lynx.cxx:519
 TMrbC2Lynx.cxx:520
 TMrbC2Lynx.cxx:521
 TMrbC2Lynx.cxx:522
 TMrbC2Lynx.cxx:523
 TMrbC2Lynx.cxx:524
 TMrbC2Lynx.cxx:525
 TMrbC2Lynx.cxx:526
 TMrbC2Lynx.cxx:527
 TMrbC2Lynx.cxx:528
 TMrbC2Lynx.cxx:529
 TMrbC2Lynx.cxx:530
 TMrbC2Lynx.cxx:531
 TMrbC2Lynx.cxx:532
 TMrbC2Lynx.cxx:533
 TMrbC2Lynx.cxx:534
 TMrbC2Lynx.cxx:535
 TMrbC2Lynx.cxx:536
 TMrbC2Lynx.cxx:537
 TMrbC2Lynx.cxx:538
 TMrbC2Lynx.cxx:539
 TMrbC2Lynx.cxx:540
 TMrbC2Lynx.cxx:541
 TMrbC2Lynx.cxx:542
 TMrbC2Lynx.cxx:543
 TMrbC2Lynx.cxx:544
 TMrbC2Lynx.cxx:545
 TMrbC2Lynx.cxx:546
 TMrbC2Lynx.cxx:547
 TMrbC2Lynx.cxx:548
 TMrbC2Lynx.cxx:549
 TMrbC2Lynx.cxx:550
 TMrbC2Lynx.cxx:551
 TMrbC2Lynx.cxx:552
 TMrbC2Lynx.cxx:553
 TMrbC2Lynx.cxx:554
 TMrbC2Lynx.cxx:555
 TMrbC2Lynx.cxx:556
 TMrbC2Lynx.cxx:557
 TMrbC2Lynx.cxx:558
 TMrbC2Lynx.cxx:559
 TMrbC2Lynx.cxx:560
 TMrbC2Lynx.cxx:561
 TMrbC2Lynx.cxx:562
 TMrbC2Lynx.cxx:563
 TMrbC2Lynx.cxx:564
 TMrbC2Lynx.cxx:565
 TMrbC2Lynx.cxx:566
 TMrbC2Lynx.cxx:567
 TMrbC2Lynx.cxx:568
 TMrbC2Lynx.cxx:569
 TMrbC2Lynx.cxx:570
 TMrbC2Lynx.cxx:571
 TMrbC2Lynx.cxx:572
 TMrbC2Lynx.cxx:573
 TMrbC2Lynx.cxx:574
 TMrbC2Lynx.cxx:575
 TMrbC2Lynx.cxx:576
 TMrbC2Lynx.cxx:577
 TMrbC2Lynx.cxx:578
 TMrbC2Lynx.cxx:579
 TMrbC2Lynx.cxx:580
 TMrbC2Lynx.cxx:581
 TMrbC2Lynx.cxx:582
 TMrbC2Lynx.cxx:583
 TMrbC2Lynx.cxx:584
 TMrbC2Lynx.cxx:585
 TMrbC2Lynx.cxx:586
 TMrbC2Lynx.cxx:587
 TMrbC2Lynx.cxx:588
 TMrbC2Lynx.cxx:589
 TMrbC2Lynx.cxx:590
 TMrbC2Lynx.cxx:591
 TMrbC2Lynx.cxx:592