// @(#)root/net:$Id$
// Author: G. Ganis  10/5/2007

/*************************************************************************
 * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TApplicationRemote                                                   //
//                                                                      //
// TApplicationRemote maps a remote session. It starts a remote session //
// and takes care of redirecting the commands to be processed to the    //
// remote session, to collect the graphic output objects and to display //
// them locally.                                                        //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include <errno.h>

#include "TApplicationRemote.h"

#include "TBrowser.h"
#include "TDirectory.h"
#include "TError.h"
#include "THashList.h"
#include "TMonitor.h"
#include "TRandom.h"
#include "TROOT.h"
#include "TServerSocket.h"
#include "TSystem.h"
#include "TRemoteObject.h"
#ifdef WIN32
#include <io.h>
#include <sys/types.h>
#endif

//
// TApplicationRemote Interrupt signal handler
//______________________________________________________________________________
Bool_t TARInterruptHandler::Notify()
{
   // TApplicationRemote interrupt handler.

   Info("Notify","Processing interrupt signal ...");

   // Handle interrupt condition on socket(s)
   fApplicationRemote->Interrupt(kRRI_Hard);

   return kTRUE;
}


ClassImp(TApplicationRemote)

static const char *gScript = "roots";
static const char *gScriptCmd = "\\\"%s %d localhost:%d/%s -d=%d\\\"";
#ifndef WIN32
static const char *gSshCmd = "ssh %s -f4 %s -R %d:localhost:%d sh -c \
   \"'(sh=\\`basename \'\\\\\\$SHELL\'\\`; \
   if test xbash = x\'\\\\\\$sh\' -o xsh = x\'\\\\\\$sh\' -o xzsh = x\'\\\\\\$sh\' -o xdash = x\'\\\\\\$sh\'; then \
      \'\\\\\\$SHELL\' -l -c %s; \
   elif test xcsh = x\'\\\\\\$sh\' -o xtcsh = x\'\\\\\\$sh\' -o xksh = x\'\\\\\\$sh\'; then \
      \'\\\\\\$SHELL\' -c %s; \
   else \
      echo \\\"Unknown shell \'\\\\\\$SHELL\'\\\"; \
   fi)'\"";
#else
static const char *gSshCmd = "ssh %s -f4 %s -R %d:localhost:%d sh -c \
   \"'(sh=`basename $SHELL`; \
   if test xbash = x$sh -o xsh = x$sh -o xzsh = x$sh -o xdash = x$sh; then \
      $SHELL -l -c %s; \
   elif test xcsh = x$sh -o xtcsh = x$sh -o xksh = x$sh; then \
      $SHELL -c %s; \
   else \
      echo \"Unknown shell $SHELL\"; \
   fi)'\"";
#endif

Int_t TApplicationRemote::fgPortAttempts = 100; // number of attempts to find a port
Int_t TApplicationRemote::fgPortLower =  49152; // lower bound for ports
Int_t TApplicationRemote::fgPortUpper =  65535; // upper bound for ports

//______________________________________________________________________________
TApplicationRemote::TApplicationRemote(const char *url, Int_t debug,
                                       const char *script)
                   : TApplication(), fUrl(url)
{
   // Main constructor: start a remote session at 'url' accepting callbacks
   // on local port 'port'; if port is already in use scan up to 'scan - 1'
   // ports starting from port + 1, i.e. port + 1, ... , port + scan - 1

   // Unique name (used also in the prompt)
   fName = fUrl.GetHost();
   if (strlen(fUrl.GetOptions()) > 0)
      fName += Form("-%s", fUrl.GetOptions());
   UserGroup_t *pw = gSystem->GetUserInfo(gSystem->GetEffectiveUid());
   TString user = (pw) ? (const char*) pw->fUser : "";
   SafeDelete(pw);
   if (strlen(fUrl.GetUser()) > 0 && user != fUrl.GetUser())
      fName.Insert(0,Form("%s@", fUrl.GetUser()));

   fIntHandler = 0;
   fSocket = 0;
   fMonitor = 0;
   fFileList = 0;
   fWorkingDir = 0;
   fRootFiles = 0;
   fReceivedObject = 0;
   ResetBit(kCollecting);

   // Create server socket; generate randomly a port to find a free one
   Int_t port = -1;
   Int_t na = fgPortAttempts;
   Long64_t now = gSystem->Now();
   gRandom->SetSeed((UInt_t)now);
   TServerSocket *ss = 0;
   while (na--) {
      port = (Int_t) (gRandom->Rndm() * (fgPortUpper - fgPortLower)) + fgPortLower;
      ss = new TServerSocket(port);
      if (ss->IsValid())
         break;
   }
   if (!ss || !ss->IsValid()) {
      Error("TApplicationRemote","unable to find a free port for connections");
      SetBit(kInvalidObject);
      return;
   }

   // Create a monitor and add the socket to it
   TMonitor *mon = new TMonitor;
   mon->Add(ss);

   // Start the remote server
   Int_t rport = (port < fgPortUpper) ? port + 1 : port - 1;
   TString sc = gScript;
   if (script && *script) {
      // script is enclosed by " ", so ignore first " char
      if (script[1] == '<') {
         if (script[2])
            sc.Form("source %s; %s", script+2, gScript);
         else
            Error("TApplicationRemote", "illegal script name <");
      } else
         sc = script;
   }
   sc.ReplaceAll("\"","");
   TString userhost = fUrl.GetHost();
   if (strlen(fUrl.GetUser()) > 0)
      userhost.Insert(0, Form("%s@", fUrl.GetUser()));
   const char *verb = "";
   if (debug > 0)
      verb = "-v";
   TString scriptCmd;
   scriptCmd.Form(gScriptCmd, sc.Data(), kRRemote_Protocol, rport, fUrl.GetFile(), debug);
   TString cmd;
   cmd.Form(gSshCmd, verb, userhost.Data(), rport, port, scriptCmd.Data(), scriptCmd.Data());
#ifdef WIN32
   // make sure that the Gpad and GUI libs are loaded
   TApplication::NeedGraphicsLibs();
   gApplication->InitializeGraphics();
#endif
   if (gDebug > 0)
      Info("TApplicationRemote", "executing: %s", cmd.Data());
   if (gSystem->Exec(cmd) != 0) {
      Info("TApplicationRemote", "an error occured during SSH connection");
      mon->DeActivateAll();
      delete mon;
      delete ss;
      SafeDelete(fSocket);
      SetBit(kInvalidObject);
      return;
   }

   // Wait for activity on the socket
   mon->Select();

   // Get the connection
   if (!(fSocket = ss->Accept())) {
      Error("TApplicationRemote", "failed to open connection");
      SetBit(kInvalidObject);
      return;
   }

   // Cleanup the monitor and the server socket
   mon->DeActivateAll();
   delete mon;
   delete ss;

   // Receive the startup message
   Int_t what;
   char buf[512];
   if (fSocket->Recv(buf, sizeof(buf), what) <= 0) {
      Error("TApplicationRemote", "failed to receive startup message");
      SafeDelete(fSocket);
      SetBit(kInvalidObject);
      return;
   }
   Printf("%s", buf);

   // Receive the protocol version run remotely
   if (fSocket->Recv(fProtocol, what) != 2*sizeof(Int_t)) {
      Error("TApplicationRemote", "failed to receive remote server protocol");
      SafeDelete(fSocket);
      SetBit(kInvalidObject);
      return;
   }
   if (fProtocol != kRRemote_Protocol)
      Info("TApplicationRemote","server runs a different protocol version: %d (vs %d)",
                     fProtocol, kRRemote_Protocol);

   TMessage *msg = 0;
   // Receive the protocol version run remotely
   if (fSocket->Recv(msg) < 0 || msg->What() != kMESS_ANY) {
      Error("TApplicationRemote", "failed to receive server info - protocol error");
      SafeDelete(fSocket);
      SetBit(kInvalidObject);
      return;
   }

   // Real host name and full path to remote log
   TString hostname;
   (*msg) >> hostname >> fLogFilePath;
   fUrl.SetHost(hostname);

   // Monitor the socket
   fMonitor = new TMonitor;
   fMonitor->Add(fSocket);

   // Set interrupt handler from now on
   fIntHandler = new TARInterruptHandler(this);

   // To get the right cleaning sequence
   gROOT->GetListOfSockets()->Remove(fSocket);
   gROOT->GetListOfSockets()->Add(this);

   fRootFiles = new TList;
   fRootFiles->SetName("Files");

   // Collect startup notifications
   Collect();

   // Done
   return;
}

//______________________________________________________________________________
TApplicationRemote::~TApplicationRemote()
{
   // Destructor

   gROOT->GetListOfSockets()->Remove(this);
   Terminate(0);
}

//______________________________________________________________________________
Int_t TApplicationRemote::Broadcast(const TMessage &mess)
{
   // Broadcast a message to the remote session.
   // Returns 0 on success, -1 in case of error.

   if (!IsValid()) return -1;

   if (fSocket->Send(mess) == -1) {
      Error("Broadcast", "could not send message");
      return -1;
   }
   // Done
   return 0;
}

//______________________________________________________________________________
Int_t TApplicationRemote::Broadcast(const char *str, Int_t kind, Int_t type)
{
   // Broadcast a character string buffer to the remote session.
   // Use kind to set the TMessage what field.
   // Returns 0 on success, -1 in case of error.

   TMessage mess(kind);
   if (kind == kMESS_ANY)
      mess << type;
   if (str) mess.WriteString(str);
   return Broadcast(mess);
}

//______________________________________________________________________________
Int_t TApplicationRemote::BroadcastObject(const TObject *obj, Int_t kind)
{
   // Broadcast an object to the remote session.
   // Use kind to set the TMessage what field.
   // Returns 0 on success, -1 in case of error.

   TMessage mess(kind);
   mess.WriteObject(obj);
   return Broadcast(mess);
}

//______________________________________________________________________________
Int_t TApplicationRemote::BroadcastRaw(const void *buffer, Int_t length)
{
   // Broadcast a raw buffer of specified length to the remote session.
   // Returns 0 on success, -1 in case of error.

   if (!IsValid()) return -1;

   if (fSocket->SendRaw(buffer, length) == -1) {
      Error("Broadcast", "could not send raw buffer");
      return -1;
   }
   // Done
   return 0;
}

//______________________________________________________________________________
Int_t TApplicationRemote::Collect(Long_t timeout)
{
   // Collect responses from the remote server.
   // Returns the number of messages received.
   // If timeout >= 0, wait at most timeout seconds (timeout = -1 by default,
   // which means wait forever).

   // Activate monitoring
   fMonitor->ActivateAll();
   if (!fMonitor->GetActive())
       return 0;

   // Timeout counter
   Long_t nto = timeout;
   if (gDebug > 2)
      Info("Collect","active: %d", fMonitor->GetActive());

   // On clients, handle Ctrl-C during collection
   if (fIntHandler)
      fIntHandler->Add();

   // We are now going to collect from the server
   SetBit(kCollecting);

   Int_t rc = 0, cnt = 0;
   while (fMonitor->GetActive() && (nto < 0 || nto > 0)) {

      // Wait for a ready socket
      TSocket *s = fMonitor->Select(1000);

      if (s && s != (TSocket *)(-1)) {
         // Get and analyse the info it did receive
         if ((rc = CollectInput()) != 0) {
            // Deactivate it if we are done with it
            fMonitor->DeActivate(s);
            if (gDebug > 2)
               Info("Collect","deactivating %p", s);
         }

         // Update counter (if no error occured)
         if (rc >= 0)
            cnt++;

      } else {
         // If not timed-out, exit if not stopped or not aborted
         // (player exits status is finished in such a case); otherwise,
         // we still need to collect the partial output info
         if (!s)
            fMonitor->DeActivateAll();
         // Decrease the timeout counter if requested
         if (s == (TSocket *)(-1) && nto > 0)
            nto--;
      }
   }

   // Collection is over
   ResetBit(kCollecting);

   // If timed-out, deactivate everything
   if (nto == 0)
      fMonitor->DeActivateAll();

   // Deactivate Ctrl-C special handler
   if (fIntHandler)
      fIntHandler->Remove();

   return cnt;
}

//______________________________________________________________________________
Int_t TApplicationRemote::CollectInput()
{
   // Collect and analyze available input from the socket.
   // Returns 0 on success, -1 if any failure occurs.

   TMessage *mess;
   Int_t rc = 0;

   char      str[512];
   TObject  *obj;
   Int_t     what;
   Bool_t    delete_mess = kTRUE;

   if (fSocket->Recv(mess) < 0) {
      SetBit(kInvalidObject);
      SafeDelete(fSocket);
      return -1;
   }
   if (!mess) {
      // we get here in case the remote server died
      SetBit(kInvalidObject);
      SafeDelete(fSocket);
      return -1;
   }

   what = mess->What();

   if (gDebug > 2)
      Info("CollectInput","what %d", what);

   switch (what) {

      case kMESS_OBJECT:
         {  // The server sent over an object: read it in memory
            TObject *o = mess->ReadObject(mess->GetClass());
            // If a canvas, draw it
            if (TString(o->ClassName()) == "TCanvas")
               o->Draw();
            else if (TString(o->ClassName()) == "TRemoteObject") {
               TRemoteObject *robj = (TRemoteObject *)o;
               if (TString(robj->GetClassName()) == "TSystemDirectory") {
                  if (fWorkingDir == 0) {
                     fWorkingDir = (TRemoteObject *)o;
                  }
               }
            }
            else if (TString(o->ClassName()) == "TList") {
               TList *list = (TList *)o;
               TRemoteObject *robj = (TRemoteObject *)list->First();
               if (robj && (TString(robj->GetClassName()) == "TFile")) {
                  TIter next(list);
                  while ((robj = (TRemoteObject *)next())) {
                     if (!fRootFiles->FindObject(robj->GetName()))
                        fRootFiles->Add(robj);
                  }
                  gROOT->RefreshBrowsers();
               }
            }
            fReceivedObject = o;
         }
         break;

      case kMESS_ANY:
         // Generic message: read out the type
         {  Int_t type;
            (*mess) >> type;

            if (gDebug > 2)
               Info("CollectInput","type %d", type);

            switch (type) {

               case kRRT_GetObject:
                  // send server the object it asks for
                  mess->ReadString(str, sizeof(str));
                  obj = gDirectory->Get(str);
                  if (obj) {
                     fSocket->SendObject(obj);
                  } else {
                     Warning("CollectInput",
                             "server requested an object that we do not have");
                     fSocket->Send(kMESS_NOTOK);
                  }
                  break;

               case kRRT_Fatal:
                  // Fatal error
                  SafeDelete(fSocket);
                  rc = -1;
                  break;

               case kRRT_LogFile:
                  {  Int_t size;
                     (*mess) >> size;
                     RecvLogFile(size);
                  }
                  break;

               case kRRT_LogDone:
                  {  Int_t st;
                    (*mess) >> st;
                     if (st < 0) {
                        // Problem: object should not be used
                        SetBit(kInvalidObject);
                     }
                     if (gDebug > 1)
                        Info("CollectInput","kRTT_LogDone: status %d", st);
                     rc = 1;
                  }
                  break;

               case kRRT_Message:
                  {  TString msg;
                     Bool_t lfeed;
                     (*mess) >> msg >> lfeed;
                     if (lfeed)
                        fprintf(stderr,"%s\n", msg.Data());
                     else
                        fprintf(stderr,"%s\r", msg.Data());
                  }
                  break;

               case kRRT_SendFile:
                  {  TString fname;
                     (*mess) >> fname;
                     // Prepare the reply
                     TMessage m(kMESS_ANY);
                     m << (Int_t) kRRT_SendFile;
                     // The server needs a file: we send also the related header
                     // if we have it.
                     char *imp = gSystem->Which(TROOT::GetMacroPath(), fname, kReadPermission);
                     if (!imp) {
                        Error("CollectInput", "file %s not found in path(s) %s",
                                         fname.Data(), TROOT::GetMacroPath());
                        m << (Bool_t) kFALSE;
                        Broadcast(m);
                     } else {
                        TString impfile = imp;
                        delete [] imp;
                        Int_t dot = impfile.Last('.');

                        // Is there any associated header file
                        Bool_t hasHeader = kTRUE;
                        TString headfile = impfile;
                        if (dot != kNPOS)
                           headfile.Remove(dot);
                        headfile += ".h";
                        if (gSystem->AccessPathName(headfile, kReadPermission)) {
                           TString h = headfile;
                           headfile.Remove(dot);
                           headfile += ".hh";
                           if (gSystem->AccessPathName(headfile, kReadPermission)) {
                              hasHeader = kFALSE;
                              if (gDebug > 0)
                                 Info("CollectInput", "no associated header file"
                                                 " found: tried: %s %s",
                                                 h.Data(), headfile.Data());
                           }
                        }

                        // Send files now;
                        m << (Bool_t) kTRUE;
                        Broadcast(m);
                        if (SendFile(impfile, kForce) == -1) {
                           Info("CollectInput", "problems sending file %s", impfile.Data());
                           return 0;
                        }
                        if (hasHeader) {
                           Broadcast(m);
                           if (SendFile(headfile, kForce) == -1) {
                              Info("CollectInput", "problems sending file %s", headfile.Data());
                              return 0;
                           }
                        }
                     }
                     // End of transmission
                     m.Reset(kMESS_ANY);
                     m << (Int_t) kRRT_SendFile;
                     m << (Bool_t) kFALSE;
                     Broadcast(m);
                  }
                  break;

               default:
                  Warning("CollectInput","unknown type received from server: %d", type);
                  break;

            }
         }
         break;

      default:
         Error("CollectInput", "unknown command received from server: %d", what);
         SetBit(kInvalidObject);
         SafeDelete(fSocket);
         rc = -1;
         break;
   }

   // Cleanup
   if (delete_mess)
      delete mess;

   // We are done successfully
   return rc;
}


//______________________________________________________________________________
void TApplicationRemote::RecvLogFile(Int_t size)
{
   // Receive the log file from the server

   const Int_t kMAXBUF = 16384;  //32768  //16384  //65536;
   char buf[kMAXBUF];

   // Append messages to active logging unit
   Int_t fdout = fileno(stdout);
   if (fdout < 0) {
      Warning("RecvLogFile", "file descriptor for outputs undefined (%d):"
                             " will not log msgs", fdout);
      return;
   }
   lseek(fdout, (off_t) 0, SEEK_END);

   Int_t  left, rec, r;
   Long_t filesize = 0;

   while (filesize < size) {
      left = Int_t(size - filesize);
      if (left > kMAXBUF)
         left = kMAXBUF;
      rec = fSocket->RecvRaw(&buf, left);
      filesize = (rec > 0) ? (filesize + rec) : filesize;
      if (rec > 0) {

         char *p = buf;
         r = rec;
         while (r) {
            Int_t w;

            w = write(fdout, p, r);

            if (w < 0) {
               SysError("RecvLogFile", "error writing to unit: %d", fdout);
               break;
            }
            r -= w;
            p += w;
         }
      } else if (rec < 0) {
         Error("RecvLogFile", "error during receiving log file");
         break;
      }
   }
}

//______________________________________________________________________________
Int_t TApplicationRemote::SendObject(const TObject *obj)
{
   // Send object to server.
   // Return 0 on success, -1 in case of error.

   if (!IsValid() || !obj) return -1;

   TMessage mess(kMESS_OBJECT);
   mess.WriteObject(obj);
   return Broadcast(mess);
}

//______________________________________________________________________________
Bool_t TApplicationRemote::CheckFile(const char *file, Long_t modtime)
{
   // Check if a file needs to be send to the server. Use the following
   // algorithm:
   //   - check if file appears in file map
   //     - if yes, get file's modtime and check against time in map,
   //       if modtime not same get md5 and compare against md5 in map,
   //       if not same return kTRUE.
   //     - if no, get file's md5 and modtime and store in file map, ask
   //       slave if file exists with specific md5, if yes return kFALSE,
   //       if no return kTRUE.
   // Returns kTRUE in case file needs to be send, returns kFALSE in case
   // file is already on remote node.

   Bool_t sendto = kFALSE;

   if (!IsValid()) return -1;

   // The filename for the cache
   TString fn = gSystem->BaseName(file);

   // Check if the file is already in the cache
   TARFileStat *fs = 0;
   if (fFileList && (fs = (TARFileStat *) fFileList->FindObject(fn))) {
      // File in cache
      if (fs->fModtime != modtime) {
         TMD5 *md5 = TMD5::FileChecksum(file);
         if (md5) {
            if ((*md5) != fs->fMD5) {
               sendto       = kTRUE;
               fs->fMD5      = *md5;
               fs->fModtime  = modtime;
            }
            delete md5;
         } else {
            Error("CheckFile", "could not calculate local MD5 check sum - dont send");
            return kFALSE;
         }
      }
   } else {
      // file not in the cache
      TMD5 *md5 = TMD5::FileChecksum(file);
      if (md5) {
         fs = new TARFileStat(fn, md5, modtime);
         if (!fFileList)
            fFileList = new THashList;
         fFileList->Add(fs);
         delete md5;
      } else {
         Error("CheckFile", "could not calculate local MD5 check sum - dont send");
         return kFALSE;
      }
      TMessage mess(kMESS_ANY);
      mess << Int_t(kRRT_CheckFile) << TString(gSystem->BaseName(file)) << fs->fMD5;
      fSocket->Send(mess);

      TMessage *reply;
      fSocket->Recv(reply);
      if (reply) {
         if (reply->What() == kMESS_ANY) {
            // Check the type
            Int_t type;
            Bool_t uptodate;
            (*reply) >> type >> uptodate;
            if (type != kRRT_CheckFile) {
               // Protocol error
               Warning("CheckFile", "received wrong type:"
                                    " %d (expected %d): protocol error?",
                                    type, (Int_t)kRRT_CheckFile);
            }
            sendto = uptodate ? kFALSE : kTRUE;
         } else {
            // Protocol error
            Error("CheckFile", "received wrong message: %d (expected %d)",
                               reply->What(), kMESS_ANY);
         }
      } else {
         Error("CheckFile", "received empty message");
      }
      // Collect logs
      Collect();
   }

   // Done
   return sendto;
}

//______________________________________________________________________________
Int_t TApplicationRemote::SendFile(const char *file, Int_t opt, const char *rfile)
{
   // Send a file to the server. Return 0 on success, -1 in case of error.
   // If defined, the full path of the remote path will be rfile.
   // The mask 'opt' is an or of ESendFileOpt:
   //
   //       kAscii  (0x0)      if set true ascii file transfer is used
   //       kBinary (0x1)      if set true binary file transfer is used
   //       kForce  (0x2)      if not set an attempt is done to find out
   //                          whether the file really needs to be downloaded
   //                          (a valid copy may already exist in the cache
   //                          from a previous run)
   //

   if (!IsValid()) return -1;

#ifndef R__WIN32
   Int_t fd = open(file, O_RDONLY);
#else
   Int_t fd = open(file, O_RDONLY | O_BINARY);
#endif
   if (fd < 0) {
      SysError("SendFile", "cannot open file %s", file);
      return -1;
   }

   // Get info about the file
   Long64_t size;
   Long_t id, flags, modtime;
   if (gSystem->GetPathInfo(file, &id, &size, &flags, &modtime) == 1) {
      Error("SendFile", "cannot stat file %s", file);
      close(fd);
      return -1;
   }
   if (size == 0) {
      Error("SendFile", "empty file %s", file);
      close(fd);
      return -1;
   }

   // Decode options
   Bool_t bin   = (opt & kBinary)  ? kTRUE : kFALSE;
   Bool_t force = (opt & kForce)   ? kTRUE : kFALSE;

   const Int_t kMAXBUF = 32768;  //16384  //65536;
   char buf[kMAXBUF];

   const char *fnam = (rfile) ? rfile : gSystem->BaseName(file);

   Bool_t sendto = force ? kTRUE : CheckFile(file, modtime);

   // The value of 'size' is used as flag remotely, so we need to
   // reset it to 0 if we are not going to send the file
   size = sendto ? size : 0;

   if (gDebug > 1 && size > 0)
      Info("SendFile", "sending file %s", file);

   snprintf(buf, kMAXBUF, "%s %d %lld", fnam, bin, size);
   if (Broadcast(buf, kMESS_ANY, kRRT_File) == -1) {
      SafeDelete(fSocket);
      return -1;
   }

   if (sendto) {

      lseek(fd, 0, SEEK_SET);

      Int_t len;
      do {
         while ((len = read(fd, buf, kMAXBUF)) < 0 && TSystem::GetErrno() == EINTR)
            TSystem::ResetErrno();

         if (len < 0) {
            SysError("SendFile", "error reading from file %s", file);
            Interrupt();
            close(fd);
            return -1;
         }

         if (len > 0 && fSocket->SendRaw(buf, len) == -1) {
            SysError("SendFile", "error writing to server @ %s:%d (now offline)",
                     fUrl.GetHost(), fUrl.GetPort());
            SafeDelete(fSocket);
            break;
         }

      } while (len > 0);
   }
   close(fd);

   // Get the log (during collection this will be done at the end
   if (!TestBit(kCollecting))
      Collect();

   // Done
   return IsValid() ? 0 : -1;
}

//______________________________________________________________________________
void TApplicationRemote::Terminate(Int_t status)
{
   // Terminate this session

   TMessage mess(kMESS_ANY);
   mess << (Int_t)kRRT_Terminate << status;
   Broadcast(mess);

   SafeDelete(fRootFiles);
   SafeDelete(fMonitor);
   SafeDelete(fSocket);
}

//______________________________________________________________________________
void TApplicationRemote::SetPortParam(Int_t lower, Int_t upper, Int_t attempts)
{
   // Set port parameters for tunnelling. A value of -1 means unchanged

   if (lower > -1)
      fgPortLower = lower;
   if (upper > -1)
      fgPortUpper = upper;
   if (attempts > -1)
      fgPortAttempts = attempts;

   ::Info("TApplicationRemote::SetPortParam","port scan: %d attempts in [%d,%d]",
          fgPortAttempts, fgPortLower, fgPortUpper);
}

//______________________________________________________________________________
Long_t TApplicationRemote::ProcessLine(const char *line, Bool_t, Int_t *)
{
   // Parse a single command line and forward the request to the remote server
   // where it will be processed. The line is either a C++ statement or an
   // interpreter command starting with a ".".
   // Return the return value of the command casted to a long.

   if (!line || !*line) return 0;

   if (!strncasecmp(line, ".q", 2)) {
      // terminate the session
      gApplication->ProcessLine(".R -close");
      return 0;
   }

   if (!strncmp(line, "?", 1)) {
      Help(line);
      return 1;
   }

   fReceivedObject = 0;

   // Init graphics
   InitializeGraphics();

   // Ok, now we pack the command and we send it over for processing
   Broadcast(line, kMESS_CINT);

   // And collect the results
   Collect();

   // Done
   return (Long_t)fReceivedObject;
   return 1;
}

//______________________________________________________________________________
void TApplicationRemote::Print(Option_t *opt) const
{
   // Print some info about this instance

   TString s(Form("OBJ: TApplicationRemote     %s", fName.Data()));
   Printf("%s", s.Data());
   if (opt && opt[0] == 'F') {
      s = "    url: ";
      if (strlen(fUrl.GetUser()) > 0)
         s += Form("%s@", fUrl.GetUser());
      s += fUrl.GetHostFQDN();
      s += Form("  logfile: %s", fLogFilePath.Data());
      Printf("%s", s.Data());
   }
}
//______________________________________________________________________________
void TApplicationRemote::Interrupt(Int_t type)
{
   // Send interrupt OOB byte to server.
   // Returns 0 if ok, -1 in case of error

   if (!IsValid()) return;

   fInterrupt = kTRUE;

#if 1
   Info("Interrupt", "*** Ctrl-C not yet enabled *** (type= %d)", type);
   return;
#else

   char oobc = (char) type;
   const int kBufSize = 1024;
   char waste[kBufSize];

   // Send one byte out-of-band message to server
   if (fSocket->SendRaw(&oobc, 1, kOob) <= 0) {
      Error("Interrupt", "error sending oobc to server");
      return;
   }

   if (type == kRRI_Hard) {
      char  oob_byte;
      int   n, nch, nbytes = 0, nloop = 0;

      // Receive the OOB byte
      while ((n = fSocket->RecvRaw(&oob_byte, 1, kOob)) < 0) {
         if (n == -2) {   // EWOULDBLOCK
            //
            // The OOB data has not yet arrived: flush the input stream
            //
            // In some systems (Solaris) regular recv() does not return upon
            // receipt of the oob byte, which makes the below call to recv()
            // block indefinitely if there are no other data in the queue.
            // FIONREAD ioctl can be used to check if there are actually any
            // data to be flushed.  If not, wait for a while for the oob byte
            // to arrive and try to read it again.
            //
            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("Interrupt", "error receiving waste from server");
               break;
            }
            nbytes += n;
         } else if (n == -3) {   // EINVAL
            //
            // The OOB data has not arrived yet
            //
            gSystem->Sleep(100);
            if (++nloop > 100) {  // 10 seconds time-out
               Error("Interrupt", "server does not respond");
               break;
            }
         } else {
            Error("Interrupt", "error receiving OOB from server");
            break;
         }
      }

      //
      // Continue flushing the input socket stream until the OOB
      // mark is reached
      //
      while (1) {
         int atmark;

         fSocket->GetOption(kAtMark, atmark);

         if (atmark)
            break;

         // find out number of bytes to read before atmark
         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("Interrupt", "error receiving waste (2) from server");
            break;
         }
         nbytes += n;
      }
      if (nbytes > 0)
         Info("Interrupt", "server synchronized: %d bytes discarded", nbytes);

      // Get log file from server after a hard interrupt
      Collect();

   } else if (type == kRRI_Soft) {

      // Get log file from server after a soft interrupt
      Collect();

   } else if (type == kRRI_Shutdown) {

      ; // nothing expected to be returned

   } else {

      // Unexpected message, just receive log file
      Collect();
   }
#endif
}

//______________________________________________________________________________
void TApplicationRemote::Browse(TBrowser *b)
{
   // Browse remote application (working directory and ROOT files).

   b->Add(fRootFiles, "ROOT Files");
   b->Add(fWorkingDir, fWorkingDir->GetTitle());
   gROOT->RefreshBrowsers();
}
 TApplicationRemote.cxx:1
 TApplicationRemote.cxx:2
 TApplicationRemote.cxx:3
 TApplicationRemote.cxx:4
 TApplicationRemote.cxx:5
 TApplicationRemote.cxx:6
 TApplicationRemote.cxx:7
 TApplicationRemote.cxx:8
 TApplicationRemote.cxx:9
 TApplicationRemote.cxx:10
 TApplicationRemote.cxx:11
 TApplicationRemote.cxx:12
 TApplicationRemote.cxx:13
 TApplicationRemote.cxx:14
 TApplicationRemote.cxx:15
 TApplicationRemote.cxx:16
 TApplicationRemote.cxx:17
 TApplicationRemote.cxx:18
 TApplicationRemote.cxx:19
 TApplicationRemote.cxx:20
 TApplicationRemote.cxx:21
 TApplicationRemote.cxx:22
 TApplicationRemote.cxx:23
 TApplicationRemote.cxx:24
 TApplicationRemote.cxx:25
 TApplicationRemote.cxx:26
 TApplicationRemote.cxx:27
 TApplicationRemote.cxx:28
 TApplicationRemote.cxx:29
 TApplicationRemote.cxx:30
 TApplicationRemote.cxx:31
 TApplicationRemote.cxx:32
 TApplicationRemote.cxx:33
 TApplicationRemote.cxx:34
 TApplicationRemote.cxx:35
 TApplicationRemote.cxx:36
 TApplicationRemote.cxx:37
 TApplicationRemote.cxx:38
 TApplicationRemote.cxx:39
 TApplicationRemote.cxx:40
 TApplicationRemote.cxx:41
 TApplicationRemote.cxx:42
 TApplicationRemote.cxx:43
 TApplicationRemote.cxx:44
 TApplicationRemote.cxx:45
 TApplicationRemote.cxx:46
 TApplicationRemote.cxx:47
 TApplicationRemote.cxx:48
 TApplicationRemote.cxx:49
 TApplicationRemote.cxx:50
 TApplicationRemote.cxx:51
 TApplicationRemote.cxx:52
 TApplicationRemote.cxx:53
 TApplicationRemote.cxx:54
 TApplicationRemote.cxx:55
 TApplicationRemote.cxx:56
 TApplicationRemote.cxx:57
 TApplicationRemote.cxx:58
 TApplicationRemote.cxx:59
 TApplicationRemote.cxx:60
 TApplicationRemote.cxx:61
 TApplicationRemote.cxx:62
 TApplicationRemote.cxx:63
 TApplicationRemote.cxx:64
 TApplicationRemote.cxx:65
 TApplicationRemote.cxx:66
 TApplicationRemote.cxx:67
 TApplicationRemote.cxx:68
 TApplicationRemote.cxx:69
 TApplicationRemote.cxx:70
 TApplicationRemote.cxx:71
 TApplicationRemote.cxx:72
 TApplicationRemote.cxx:73
 TApplicationRemote.cxx:74
 TApplicationRemote.cxx:75
 TApplicationRemote.cxx:76
 TApplicationRemote.cxx:77
 TApplicationRemote.cxx:78
 TApplicationRemote.cxx:79
 TApplicationRemote.cxx:80
 TApplicationRemote.cxx:81
 TApplicationRemote.cxx:82
 TApplicationRemote.cxx:83
 TApplicationRemote.cxx:84
 TApplicationRemote.cxx:85
 TApplicationRemote.cxx:86
 TApplicationRemote.cxx:87
 TApplicationRemote.cxx:88
 TApplicationRemote.cxx:89
 TApplicationRemote.cxx:90
 TApplicationRemote.cxx:91
 TApplicationRemote.cxx:92
 TApplicationRemote.cxx:93
 TApplicationRemote.cxx:94
 TApplicationRemote.cxx:95
 TApplicationRemote.cxx:96
 TApplicationRemote.cxx:97
 TApplicationRemote.cxx:98
 TApplicationRemote.cxx:99
 TApplicationRemote.cxx:100
 TApplicationRemote.cxx:101
 TApplicationRemote.cxx:102
 TApplicationRemote.cxx:103
 TApplicationRemote.cxx:104
 TApplicationRemote.cxx:105
 TApplicationRemote.cxx:106
 TApplicationRemote.cxx:107
 TApplicationRemote.cxx:108
 TApplicationRemote.cxx:109
 TApplicationRemote.cxx:110
 TApplicationRemote.cxx:111
 TApplicationRemote.cxx:112
 TApplicationRemote.cxx:113
 TApplicationRemote.cxx:114
 TApplicationRemote.cxx:115
 TApplicationRemote.cxx:116
 TApplicationRemote.cxx:117
 TApplicationRemote.cxx:118
 TApplicationRemote.cxx:119
 TApplicationRemote.cxx:120
 TApplicationRemote.cxx:121
 TApplicationRemote.cxx:122
 TApplicationRemote.cxx:123
 TApplicationRemote.cxx:124
 TApplicationRemote.cxx:125
 TApplicationRemote.cxx:126
 TApplicationRemote.cxx:127
 TApplicationRemote.cxx:128
 TApplicationRemote.cxx:129
 TApplicationRemote.cxx:130
 TApplicationRemote.cxx:131
 TApplicationRemote.cxx:132
 TApplicationRemote.cxx:133
 TApplicationRemote.cxx:134
 TApplicationRemote.cxx:135
 TApplicationRemote.cxx:136
 TApplicationRemote.cxx:137
 TApplicationRemote.cxx:138
 TApplicationRemote.cxx:139
 TApplicationRemote.cxx:140
 TApplicationRemote.cxx:141
 TApplicationRemote.cxx:142
 TApplicationRemote.cxx:143
 TApplicationRemote.cxx:144
 TApplicationRemote.cxx:145
 TApplicationRemote.cxx:146
 TApplicationRemote.cxx:147
 TApplicationRemote.cxx:148
 TApplicationRemote.cxx:149
 TApplicationRemote.cxx:150
 TApplicationRemote.cxx:151
 TApplicationRemote.cxx:152
 TApplicationRemote.cxx:153
 TApplicationRemote.cxx:154
 TApplicationRemote.cxx:155
 TApplicationRemote.cxx:156
 TApplicationRemote.cxx:157
 TApplicationRemote.cxx:158
 TApplicationRemote.cxx:159
 TApplicationRemote.cxx:160
 TApplicationRemote.cxx:161
 TApplicationRemote.cxx:162
 TApplicationRemote.cxx:163
 TApplicationRemote.cxx:164
 TApplicationRemote.cxx:165
 TApplicationRemote.cxx:166
 TApplicationRemote.cxx:167
 TApplicationRemote.cxx:168
 TApplicationRemote.cxx:169
 TApplicationRemote.cxx:170
 TApplicationRemote.cxx:171
 TApplicationRemote.cxx:172
 TApplicationRemote.cxx:173
 TApplicationRemote.cxx:174
 TApplicationRemote.cxx:175
 TApplicationRemote.cxx:176
 TApplicationRemote.cxx:177
 TApplicationRemote.cxx:178
 TApplicationRemote.cxx:179
 TApplicationRemote.cxx:180
 TApplicationRemote.cxx:181
 TApplicationRemote.cxx:182
 TApplicationRemote.cxx:183
 TApplicationRemote.cxx:184
 TApplicationRemote.cxx:185
 TApplicationRemote.cxx:186
 TApplicationRemote.cxx:187
 TApplicationRemote.cxx:188
 TApplicationRemote.cxx:189
 TApplicationRemote.cxx:190
 TApplicationRemote.cxx:191
 TApplicationRemote.cxx:192
 TApplicationRemote.cxx:193
 TApplicationRemote.cxx:194
 TApplicationRemote.cxx:195
 TApplicationRemote.cxx:196
 TApplicationRemote.cxx:197
 TApplicationRemote.cxx:198
 TApplicationRemote.cxx:199
 TApplicationRemote.cxx:200
 TApplicationRemote.cxx:201
 TApplicationRemote.cxx:202
 TApplicationRemote.cxx:203
 TApplicationRemote.cxx:204
 TApplicationRemote.cxx:205
 TApplicationRemote.cxx:206
 TApplicationRemote.cxx:207
 TApplicationRemote.cxx:208
 TApplicationRemote.cxx:209
 TApplicationRemote.cxx:210
 TApplicationRemote.cxx:211
 TApplicationRemote.cxx:212
 TApplicationRemote.cxx:213
 TApplicationRemote.cxx:214
 TApplicationRemote.cxx:215
 TApplicationRemote.cxx:216
 TApplicationRemote.cxx:217
 TApplicationRemote.cxx:218
 TApplicationRemote.cxx:219
 TApplicationRemote.cxx:220
 TApplicationRemote.cxx:221
 TApplicationRemote.cxx:222
 TApplicationRemote.cxx:223
 TApplicationRemote.cxx:224
 TApplicationRemote.cxx:225
 TApplicationRemote.cxx:226
 TApplicationRemote.cxx:227
 TApplicationRemote.cxx:228
 TApplicationRemote.cxx:229
 TApplicationRemote.cxx:230
 TApplicationRemote.cxx:231
 TApplicationRemote.cxx:232
 TApplicationRemote.cxx:233
 TApplicationRemote.cxx:234
 TApplicationRemote.cxx:235
 TApplicationRemote.cxx:236
 TApplicationRemote.cxx:237
 TApplicationRemote.cxx:238
 TApplicationRemote.cxx:239
 TApplicationRemote.cxx:240
 TApplicationRemote.cxx:241
 TApplicationRemote.cxx:242
 TApplicationRemote.cxx:243
 TApplicationRemote.cxx:244
 TApplicationRemote.cxx:245
 TApplicationRemote.cxx:246
 TApplicationRemote.cxx:247
 TApplicationRemote.cxx:248
 TApplicationRemote.cxx:249
 TApplicationRemote.cxx:250
 TApplicationRemote.cxx:251
 TApplicationRemote.cxx:252
 TApplicationRemote.cxx:253
 TApplicationRemote.cxx:254
 TApplicationRemote.cxx:255
 TApplicationRemote.cxx:256
 TApplicationRemote.cxx:257
 TApplicationRemote.cxx:258
 TApplicationRemote.cxx:259
 TApplicationRemote.cxx:260
 TApplicationRemote.cxx:261
 TApplicationRemote.cxx:262
 TApplicationRemote.cxx:263
 TApplicationRemote.cxx:264
 TApplicationRemote.cxx:265
 TApplicationRemote.cxx:266
 TApplicationRemote.cxx:267
 TApplicationRemote.cxx:268
 TApplicationRemote.cxx:269
 TApplicationRemote.cxx:270
 TApplicationRemote.cxx:271
 TApplicationRemote.cxx:272
 TApplicationRemote.cxx:273
 TApplicationRemote.cxx:274
 TApplicationRemote.cxx:275
 TApplicationRemote.cxx:276
 TApplicationRemote.cxx:277
 TApplicationRemote.cxx:278
 TApplicationRemote.cxx:279
 TApplicationRemote.cxx:280
 TApplicationRemote.cxx:281
 TApplicationRemote.cxx:282
 TApplicationRemote.cxx:283
 TApplicationRemote.cxx:284
 TApplicationRemote.cxx:285
 TApplicationRemote.cxx:286
 TApplicationRemote.cxx:287
 TApplicationRemote.cxx:288
 TApplicationRemote.cxx:289
 TApplicationRemote.cxx:290
 TApplicationRemote.cxx:291
 TApplicationRemote.cxx:292
 TApplicationRemote.cxx:293
 TApplicationRemote.cxx:294
 TApplicationRemote.cxx:295
 TApplicationRemote.cxx:296
 TApplicationRemote.cxx:297
 TApplicationRemote.cxx:298
 TApplicationRemote.cxx:299
 TApplicationRemote.cxx:300
 TApplicationRemote.cxx:301
 TApplicationRemote.cxx:302
 TApplicationRemote.cxx:303
 TApplicationRemote.cxx:304
 TApplicationRemote.cxx:305
 TApplicationRemote.cxx:306
 TApplicationRemote.cxx:307
 TApplicationRemote.cxx:308
 TApplicationRemote.cxx:309
 TApplicationRemote.cxx:310
 TApplicationRemote.cxx:311
 TApplicationRemote.cxx:312
 TApplicationRemote.cxx:313
 TApplicationRemote.cxx:314
 TApplicationRemote.cxx:315
 TApplicationRemote.cxx:316
 TApplicationRemote.cxx:317
 TApplicationRemote.cxx:318
 TApplicationRemote.cxx:319
 TApplicationRemote.cxx:320
 TApplicationRemote.cxx:321
 TApplicationRemote.cxx:322
 TApplicationRemote.cxx:323
 TApplicationRemote.cxx:324
 TApplicationRemote.cxx:325
 TApplicationRemote.cxx:326
 TApplicationRemote.cxx:327
 TApplicationRemote.cxx:328
 TApplicationRemote.cxx:329
 TApplicationRemote.cxx:330
 TApplicationRemote.cxx:331
 TApplicationRemote.cxx:332
 TApplicationRemote.cxx:333
 TApplicationRemote.cxx:334
 TApplicationRemote.cxx:335
 TApplicationRemote.cxx:336
 TApplicationRemote.cxx:337
 TApplicationRemote.cxx:338
 TApplicationRemote.cxx:339
 TApplicationRemote.cxx:340
 TApplicationRemote.cxx:341
 TApplicationRemote.cxx:342
 TApplicationRemote.cxx:343
 TApplicationRemote.cxx:344
 TApplicationRemote.cxx:345
 TApplicationRemote.cxx:346
 TApplicationRemote.cxx:347
 TApplicationRemote.cxx:348
 TApplicationRemote.cxx:349
 TApplicationRemote.cxx:350
 TApplicationRemote.cxx:351
 TApplicationRemote.cxx:352
 TApplicationRemote.cxx:353
 TApplicationRemote.cxx:354
 TApplicationRemote.cxx:355
 TApplicationRemote.cxx:356
 TApplicationRemote.cxx:357
 TApplicationRemote.cxx:358
 TApplicationRemote.cxx:359
 TApplicationRemote.cxx:360
 TApplicationRemote.cxx:361
 TApplicationRemote.cxx:362
 TApplicationRemote.cxx:363
 TApplicationRemote.cxx:364
 TApplicationRemote.cxx:365
 TApplicationRemote.cxx:366
 TApplicationRemote.cxx:367
 TApplicationRemote.cxx:368
 TApplicationRemote.cxx:369
 TApplicationRemote.cxx:370
 TApplicationRemote.cxx:371
 TApplicationRemote.cxx:372
 TApplicationRemote.cxx:373
 TApplicationRemote.cxx:374
 TApplicationRemote.cxx:375
 TApplicationRemote.cxx:376
 TApplicationRemote.cxx:377
 TApplicationRemote.cxx:378
 TApplicationRemote.cxx:379
 TApplicationRemote.cxx:380
 TApplicationRemote.cxx:381
 TApplicationRemote.cxx:382
 TApplicationRemote.cxx:383
 TApplicationRemote.cxx:384
 TApplicationRemote.cxx:385
 TApplicationRemote.cxx:386
 TApplicationRemote.cxx:387
 TApplicationRemote.cxx:388
 TApplicationRemote.cxx:389
 TApplicationRemote.cxx:390
 TApplicationRemote.cxx:391
 TApplicationRemote.cxx:392
 TApplicationRemote.cxx:393
 TApplicationRemote.cxx:394
 TApplicationRemote.cxx:395
 TApplicationRemote.cxx:396
 TApplicationRemote.cxx:397
 TApplicationRemote.cxx:398
 TApplicationRemote.cxx:399
 TApplicationRemote.cxx:400
 TApplicationRemote.cxx:401
 TApplicationRemote.cxx:402
 TApplicationRemote.cxx:403
 TApplicationRemote.cxx:404
 TApplicationRemote.cxx:405
 TApplicationRemote.cxx:406
 TApplicationRemote.cxx:407
 TApplicationRemote.cxx:408
 TApplicationRemote.cxx:409
 TApplicationRemote.cxx:410
 TApplicationRemote.cxx:411
 TApplicationRemote.cxx:412
 TApplicationRemote.cxx:413
 TApplicationRemote.cxx:414
 TApplicationRemote.cxx:415
 TApplicationRemote.cxx:416
 TApplicationRemote.cxx:417
 TApplicationRemote.cxx:418
 TApplicationRemote.cxx:419
 TApplicationRemote.cxx:420
 TApplicationRemote.cxx:421
 TApplicationRemote.cxx:422
 TApplicationRemote.cxx:423
 TApplicationRemote.cxx:424
 TApplicationRemote.cxx:425
 TApplicationRemote.cxx:426
 TApplicationRemote.cxx:427
 TApplicationRemote.cxx:428
 TApplicationRemote.cxx:429
 TApplicationRemote.cxx:430
 TApplicationRemote.cxx:431
 TApplicationRemote.cxx:432
 TApplicationRemote.cxx:433
 TApplicationRemote.cxx:434
 TApplicationRemote.cxx:435
 TApplicationRemote.cxx:436
 TApplicationRemote.cxx:437
 TApplicationRemote.cxx:438
 TApplicationRemote.cxx:439
 TApplicationRemote.cxx:440
 TApplicationRemote.cxx:441
 TApplicationRemote.cxx:442
 TApplicationRemote.cxx:443
 TApplicationRemote.cxx:444
 TApplicationRemote.cxx:445
 TApplicationRemote.cxx:446
 TApplicationRemote.cxx:447
 TApplicationRemote.cxx:448
 TApplicationRemote.cxx:449
 TApplicationRemote.cxx:450
 TApplicationRemote.cxx:451
 TApplicationRemote.cxx:452
 TApplicationRemote.cxx:453
 TApplicationRemote.cxx:454
 TApplicationRemote.cxx:455
 TApplicationRemote.cxx:456
 TApplicationRemote.cxx:457
 TApplicationRemote.cxx:458
 TApplicationRemote.cxx:459
 TApplicationRemote.cxx:460
 TApplicationRemote.cxx:461
 TApplicationRemote.cxx:462
 TApplicationRemote.cxx:463
 TApplicationRemote.cxx:464
 TApplicationRemote.cxx:465
 TApplicationRemote.cxx:466
 TApplicationRemote.cxx:467
 TApplicationRemote.cxx:468
 TApplicationRemote.cxx:469
 TApplicationRemote.cxx:470
 TApplicationRemote.cxx:471
 TApplicationRemote.cxx:472
 TApplicationRemote.cxx:473
 TApplicationRemote.cxx:474
 TApplicationRemote.cxx:475
 TApplicationRemote.cxx:476
 TApplicationRemote.cxx:477
 TApplicationRemote.cxx:478
 TApplicationRemote.cxx:479
 TApplicationRemote.cxx:480
 TApplicationRemote.cxx:481
 TApplicationRemote.cxx:482
 TApplicationRemote.cxx:483
 TApplicationRemote.cxx:484
 TApplicationRemote.cxx:485
 TApplicationRemote.cxx:486
 TApplicationRemote.cxx:487
 TApplicationRemote.cxx:488
 TApplicationRemote.cxx:489
 TApplicationRemote.cxx:490
 TApplicationRemote.cxx:491
 TApplicationRemote.cxx:492
 TApplicationRemote.cxx:493
 TApplicationRemote.cxx:494
 TApplicationRemote.cxx:495
 TApplicationRemote.cxx:496
 TApplicationRemote.cxx:497
 TApplicationRemote.cxx:498
 TApplicationRemote.cxx:499
 TApplicationRemote.cxx:500
 TApplicationRemote.cxx:501
 TApplicationRemote.cxx:502
 TApplicationRemote.cxx:503
 TApplicationRemote.cxx:504
 TApplicationRemote.cxx:505
 TApplicationRemote.cxx:506
 TApplicationRemote.cxx:507
 TApplicationRemote.cxx:508
 TApplicationRemote.cxx:509
 TApplicationRemote.cxx:510
 TApplicationRemote.cxx:511
 TApplicationRemote.cxx:512
 TApplicationRemote.cxx:513
 TApplicationRemote.cxx:514
 TApplicationRemote.cxx:515
 TApplicationRemote.cxx:516
 TApplicationRemote.cxx:517
 TApplicationRemote.cxx:518
 TApplicationRemote.cxx:519
 TApplicationRemote.cxx:520
 TApplicationRemote.cxx:521
 TApplicationRemote.cxx:522
 TApplicationRemote.cxx:523
 TApplicationRemote.cxx:524
 TApplicationRemote.cxx:525
 TApplicationRemote.cxx:526
 TApplicationRemote.cxx:527
 TApplicationRemote.cxx:528
 TApplicationRemote.cxx:529
 TApplicationRemote.cxx:530
 TApplicationRemote.cxx:531
 TApplicationRemote.cxx:532
 TApplicationRemote.cxx:533
 TApplicationRemote.cxx:534
 TApplicationRemote.cxx:535
 TApplicationRemote.cxx:536
 TApplicationRemote.cxx:537
 TApplicationRemote.cxx:538
 TApplicationRemote.cxx:539
 TApplicationRemote.cxx:540
 TApplicationRemote.cxx:541
 TApplicationRemote.cxx:542
 TApplicationRemote.cxx:543
 TApplicationRemote.cxx:544
 TApplicationRemote.cxx:545
 TApplicationRemote.cxx:546
 TApplicationRemote.cxx:547
 TApplicationRemote.cxx:548
 TApplicationRemote.cxx:549
 TApplicationRemote.cxx:550
 TApplicationRemote.cxx:551
 TApplicationRemote.cxx:552
 TApplicationRemote.cxx:553
 TApplicationRemote.cxx:554
 TApplicationRemote.cxx:555
 TApplicationRemote.cxx:556
 TApplicationRemote.cxx:557
 TApplicationRemote.cxx:558
 TApplicationRemote.cxx:559
 TApplicationRemote.cxx:560
 TApplicationRemote.cxx:561
 TApplicationRemote.cxx:562
 TApplicationRemote.cxx:563
 TApplicationRemote.cxx:564
 TApplicationRemote.cxx:565
 TApplicationRemote.cxx:566
 TApplicationRemote.cxx:567
 TApplicationRemote.cxx:568
 TApplicationRemote.cxx:569
 TApplicationRemote.cxx:570
 TApplicationRemote.cxx:571
 TApplicationRemote.cxx:572
 TApplicationRemote.cxx:573
 TApplicationRemote.cxx:574
 TApplicationRemote.cxx:575
 TApplicationRemote.cxx:576
 TApplicationRemote.cxx:577
 TApplicationRemote.cxx:578
 TApplicationRemote.cxx:579
 TApplicationRemote.cxx:580
 TApplicationRemote.cxx:581
 TApplicationRemote.cxx:582
 TApplicationRemote.cxx:583
 TApplicationRemote.cxx:584
 TApplicationRemote.cxx:585
 TApplicationRemote.cxx:586
 TApplicationRemote.cxx:587
 TApplicationRemote.cxx:588
 TApplicationRemote.cxx:589
 TApplicationRemote.cxx:590
 TApplicationRemote.cxx:591
 TApplicationRemote.cxx:592
 TApplicationRemote.cxx:593
 TApplicationRemote.cxx:594
 TApplicationRemote.cxx:595
 TApplicationRemote.cxx:596
 TApplicationRemote.cxx:597
 TApplicationRemote.cxx:598
 TApplicationRemote.cxx:599
 TApplicationRemote.cxx:600
 TApplicationRemote.cxx:601
 TApplicationRemote.cxx:602
 TApplicationRemote.cxx:603
 TApplicationRemote.cxx:604
 TApplicationRemote.cxx:605
 TApplicationRemote.cxx:606
 TApplicationRemote.cxx:607
 TApplicationRemote.cxx:608
 TApplicationRemote.cxx:609
 TApplicationRemote.cxx:610
 TApplicationRemote.cxx:611
 TApplicationRemote.cxx:612
 TApplicationRemote.cxx:613
 TApplicationRemote.cxx:614
 TApplicationRemote.cxx:615
 TApplicationRemote.cxx:616
 TApplicationRemote.cxx:617
 TApplicationRemote.cxx:618
 TApplicationRemote.cxx:619
 TApplicationRemote.cxx:620
 TApplicationRemote.cxx:621
 TApplicationRemote.cxx:622
 TApplicationRemote.cxx:623
 TApplicationRemote.cxx:624
 TApplicationRemote.cxx:625
 TApplicationRemote.cxx:626
 TApplicationRemote.cxx:627
 TApplicationRemote.cxx:628
 TApplicationRemote.cxx:629
 TApplicationRemote.cxx:630
 TApplicationRemote.cxx:631
 TApplicationRemote.cxx:632
 TApplicationRemote.cxx:633
 TApplicationRemote.cxx:634
 TApplicationRemote.cxx:635
 TApplicationRemote.cxx:636
 TApplicationRemote.cxx:637
 TApplicationRemote.cxx:638
 TApplicationRemote.cxx:639
 TApplicationRemote.cxx:640
 TApplicationRemote.cxx:641
 TApplicationRemote.cxx:642
 TApplicationRemote.cxx:643
 TApplicationRemote.cxx:644
 TApplicationRemote.cxx:645
 TApplicationRemote.cxx:646
 TApplicationRemote.cxx:647
 TApplicationRemote.cxx:648
 TApplicationRemote.cxx:649
 TApplicationRemote.cxx:650
 TApplicationRemote.cxx:651
 TApplicationRemote.cxx:652
 TApplicationRemote.cxx:653
 TApplicationRemote.cxx:654
 TApplicationRemote.cxx:655
 TApplicationRemote.cxx:656
 TApplicationRemote.cxx:657
 TApplicationRemote.cxx:658
 TApplicationRemote.cxx:659
 TApplicationRemote.cxx:660
 TApplicationRemote.cxx:661
 TApplicationRemote.cxx:662
 TApplicationRemote.cxx:663
 TApplicationRemote.cxx:664
 TApplicationRemote.cxx:665
 TApplicationRemote.cxx:666
 TApplicationRemote.cxx:667
 TApplicationRemote.cxx:668
 TApplicationRemote.cxx:669
 TApplicationRemote.cxx:670
 TApplicationRemote.cxx:671
 TApplicationRemote.cxx:672
 TApplicationRemote.cxx:673
 TApplicationRemote.cxx:674
 TApplicationRemote.cxx:675
 TApplicationRemote.cxx:676
 TApplicationRemote.cxx:677
 TApplicationRemote.cxx:678
 TApplicationRemote.cxx:679
 TApplicationRemote.cxx:680
 TApplicationRemote.cxx:681
 TApplicationRemote.cxx:682
 TApplicationRemote.cxx:683
 TApplicationRemote.cxx:684
 TApplicationRemote.cxx:685
 TApplicationRemote.cxx:686
 TApplicationRemote.cxx:687
 TApplicationRemote.cxx:688
 TApplicationRemote.cxx:689
 TApplicationRemote.cxx:690
 TApplicationRemote.cxx:691
 TApplicationRemote.cxx:692
 TApplicationRemote.cxx:693
 TApplicationRemote.cxx:694
 TApplicationRemote.cxx:695
 TApplicationRemote.cxx:696
 TApplicationRemote.cxx:697
 TApplicationRemote.cxx:698
 TApplicationRemote.cxx:699
 TApplicationRemote.cxx:700
 TApplicationRemote.cxx:701
 TApplicationRemote.cxx:702
 TApplicationRemote.cxx:703
 TApplicationRemote.cxx:704
 TApplicationRemote.cxx:705
 TApplicationRemote.cxx:706
 TApplicationRemote.cxx:707
 TApplicationRemote.cxx:708
 TApplicationRemote.cxx:709
 TApplicationRemote.cxx:710
 TApplicationRemote.cxx:711
 TApplicationRemote.cxx:712
 TApplicationRemote.cxx:713
 TApplicationRemote.cxx:714
 TApplicationRemote.cxx:715
 TApplicationRemote.cxx:716
 TApplicationRemote.cxx:717
 TApplicationRemote.cxx:718
 TApplicationRemote.cxx:719
 TApplicationRemote.cxx:720
 TApplicationRemote.cxx:721
 TApplicationRemote.cxx:722
 TApplicationRemote.cxx:723
 TApplicationRemote.cxx:724
 TApplicationRemote.cxx:725
 TApplicationRemote.cxx:726
 TApplicationRemote.cxx:727
 TApplicationRemote.cxx:728
 TApplicationRemote.cxx:729
 TApplicationRemote.cxx:730
 TApplicationRemote.cxx:731
 TApplicationRemote.cxx:732
 TApplicationRemote.cxx:733
 TApplicationRemote.cxx:734
 TApplicationRemote.cxx:735
 TApplicationRemote.cxx:736
 TApplicationRemote.cxx:737
 TApplicationRemote.cxx:738
 TApplicationRemote.cxx:739
 TApplicationRemote.cxx:740
 TApplicationRemote.cxx:741
 TApplicationRemote.cxx:742
 TApplicationRemote.cxx:743
 TApplicationRemote.cxx:744
 TApplicationRemote.cxx:745
 TApplicationRemote.cxx:746
 TApplicationRemote.cxx:747
 TApplicationRemote.cxx:748
 TApplicationRemote.cxx:749
 TApplicationRemote.cxx:750
 TApplicationRemote.cxx:751
 TApplicationRemote.cxx:752
 TApplicationRemote.cxx:753
 TApplicationRemote.cxx:754
 TApplicationRemote.cxx:755
 TApplicationRemote.cxx:756
 TApplicationRemote.cxx:757
 TApplicationRemote.cxx:758
 TApplicationRemote.cxx:759
 TApplicationRemote.cxx:760
 TApplicationRemote.cxx:761
 TApplicationRemote.cxx:762
 TApplicationRemote.cxx:763
 TApplicationRemote.cxx:764
 TApplicationRemote.cxx:765
 TApplicationRemote.cxx:766
 TApplicationRemote.cxx:767
 TApplicationRemote.cxx:768
 TApplicationRemote.cxx:769
 TApplicationRemote.cxx:770
 TApplicationRemote.cxx:771
 TApplicationRemote.cxx:772
 TApplicationRemote.cxx:773
 TApplicationRemote.cxx:774
 TApplicationRemote.cxx:775
 TApplicationRemote.cxx:776
 TApplicationRemote.cxx:777
 TApplicationRemote.cxx:778
 TApplicationRemote.cxx:779
 TApplicationRemote.cxx:780
 TApplicationRemote.cxx:781
 TApplicationRemote.cxx:782
 TApplicationRemote.cxx:783
 TApplicationRemote.cxx:784
 TApplicationRemote.cxx:785
 TApplicationRemote.cxx:786
 TApplicationRemote.cxx:787
 TApplicationRemote.cxx:788
 TApplicationRemote.cxx:789
 TApplicationRemote.cxx:790
 TApplicationRemote.cxx:791
 TApplicationRemote.cxx:792
 TApplicationRemote.cxx:793
 TApplicationRemote.cxx:794
 TApplicationRemote.cxx:795
 TApplicationRemote.cxx:796
 TApplicationRemote.cxx:797
 TApplicationRemote.cxx:798
 TApplicationRemote.cxx:799
 TApplicationRemote.cxx:800
 TApplicationRemote.cxx:801
 TApplicationRemote.cxx:802
 TApplicationRemote.cxx:803
 TApplicationRemote.cxx:804
 TApplicationRemote.cxx:805
 TApplicationRemote.cxx:806
 TApplicationRemote.cxx:807
 TApplicationRemote.cxx:808
 TApplicationRemote.cxx:809
 TApplicationRemote.cxx:810
 TApplicationRemote.cxx:811
 TApplicationRemote.cxx:812
 TApplicationRemote.cxx:813
 TApplicationRemote.cxx:814
 TApplicationRemote.cxx:815
 TApplicationRemote.cxx:816
 TApplicationRemote.cxx:817
 TApplicationRemote.cxx:818
 TApplicationRemote.cxx:819
 TApplicationRemote.cxx:820
 TApplicationRemote.cxx:821
 TApplicationRemote.cxx:822
 TApplicationRemote.cxx:823
 TApplicationRemote.cxx:824
 TApplicationRemote.cxx:825
 TApplicationRemote.cxx:826
 TApplicationRemote.cxx:827
 TApplicationRemote.cxx:828
 TApplicationRemote.cxx:829
 TApplicationRemote.cxx:830
 TApplicationRemote.cxx:831
 TApplicationRemote.cxx:832
 TApplicationRemote.cxx:833
 TApplicationRemote.cxx:834
 TApplicationRemote.cxx:835
 TApplicationRemote.cxx:836
 TApplicationRemote.cxx:837
 TApplicationRemote.cxx:838
 TApplicationRemote.cxx:839
 TApplicationRemote.cxx:840
 TApplicationRemote.cxx:841
 TApplicationRemote.cxx:842
 TApplicationRemote.cxx:843
 TApplicationRemote.cxx:844
 TApplicationRemote.cxx:845
 TApplicationRemote.cxx:846
 TApplicationRemote.cxx:847
 TApplicationRemote.cxx:848
 TApplicationRemote.cxx:849
 TApplicationRemote.cxx:850
 TApplicationRemote.cxx:851
 TApplicationRemote.cxx:852
 TApplicationRemote.cxx:853
 TApplicationRemote.cxx:854
 TApplicationRemote.cxx:855
 TApplicationRemote.cxx:856
 TApplicationRemote.cxx:857
 TApplicationRemote.cxx:858
 TApplicationRemote.cxx:859
 TApplicationRemote.cxx:860
 TApplicationRemote.cxx:861
 TApplicationRemote.cxx:862
 TApplicationRemote.cxx:863
 TApplicationRemote.cxx:864
 TApplicationRemote.cxx:865
 TApplicationRemote.cxx:866
 TApplicationRemote.cxx:867
 TApplicationRemote.cxx:868
 TApplicationRemote.cxx:869
 TApplicationRemote.cxx:870
 TApplicationRemote.cxx:871
 TApplicationRemote.cxx:872
 TApplicationRemote.cxx:873
 TApplicationRemote.cxx:874
 TApplicationRemote.cxx:875
 TApplicationRemote.cxx:876
 TApplicationRemote.cxx:877
 TApplicationRemote.cxx:878
 TApplicationRemote.cxx:879
 TApplicationRemote.cxx:880
 TApplicationRemote.cxx:881
 TApplicationRemote.cxx:882
 TApplicationRemote.cxx:883
 TApplicationRemote.cxx:884
 TApplicationRemote.cxx:885
 TApplicationRemote.cxx:886
 TApplicationRemote.cxx:887
 TApplicationRemote.cxx:888
 TApplicationRemote.cxx:889
 TApplicationRemote.cxx:890
 TApplicationRemote.cxx:891
 TApplicationRemote.cxx:892
 TApplicationRemote.cxx:893
 TApplicationRemote.cxx:894
 TApplicationRemote.cxx:895
 TApplicationRemote.cxx:896
 TApplicationRemote.cxx:897
 TApplicationRemote.cxx:898
 TApplicationRemote.cxx:899
 TApplicationRemote.cxx:900
 TApplicationRemote.cxx:901
 TApplicationRemote.cxx:902
 TApplicationRemote.cxx:903
 TApplicationRemote.cxx:904
 TApplicationRemote.cxx:905
 TApplicationRemote.cxx:906
 TApplicationRemote.cxx:907
 TApplicationRemote.cxx:908
 TApplicationRemote.cxx:909
 TApplicationRemote.cxx:910
 TApplicationRemote.cxx:911
 TApplicationRemote.cxx:912
 TApplicationRemote.cxx:913
 TApplicationRemote.cxx:914
 TApplicationRemote.cxx:915
 TApplicationRemote.cxx:916
 TApplicationRemote.cxx:917
 TApplicationRemote.cxx:918
 TApplicationRemote.cxx:919
 TApplicationRemote.cxx:920
 TApplicationRemote.cxx:921
 TApplicationRemote.cxx:922
 TApplicationRemote.cxx:923
 TApplicationRemote.cxx:924
 TApplicationRemote.cxx:925
 TApplicationRemote.cxx:926
 TApplicationRemote.cxx:927
 TApplicationRemote.cxx:928
 TApplicationRemote.cxx:929
 TApplicationRemote.cxx:930
 TApplicationRemote.cxx:931
 TApplicationRemote.cxx:932
 TApplicationRemote.cxx:933
 TApplicationRemote.cxx:934
 TApplicationRemote.cxx:935
 TApplicationRemote.cxx:936
 TApplicationRemote.cxx:937
 TApplicationRemote.cxx:938
 TApplicationRemote.cxx:939
 TApplicationRemote.cxx:940
 TApplicationRemote.cxx:941
 TApplicationRemote.cxx:942
 TApplicationRemote.cxx:943
 TApplicationRemote.cxx:944
 TApplicationRemote.cxx:945
 TApplicationRemote.cxx:946
 TApplicationRemote.cxx:947
 TApplicationRemote.cxx:948
 TApplicationRemote.cxx:949
 TApplicationRemote.cxx:950
 TApplicationRemote.cxx:951
 TApplicationRemote.cxx:952
 TApplicationRemote.cxx:953
 TApplicationRemote.cxx:954
 TApplicationRemote.cxx:955
 TApplicationRemote.cxx:956
 TApplicationRemote.cxx:957
 TApplicationRemote.cxx:958
 TApplicationRemote.cxx:959
 TApplicationRemote.cxx:960
 TApplicationRemote.cxx:961
 TApplicationRemote.cxx:962
 TApplicationRemote.cxx:963
 TApplicationRemote.cxx:964
 TApplicationRemote.cxx:965
 TApplicationRemote.cxx:966
 TApplicationRemote.cxx:967
 TApplicationRemote.cxx:968
 TApplicationRemote.cxx:969
 TApplicationRemote.cxx:970
 TApplicationRemote.cxx:971
 TApplicationRemote.cxx:972
 TApplicationRemote.cxx:973
 TApplicationRemote.cxx:974
 TApplicationRemote.cxx:975
 TApplicationRemote.cxx:976
 TApplicationRemote.cxx:977
 TApplicationRemote.cxx:978
 TApplicationRemote.cxx:979
 TApplicationRemote.cxx:980
 TApplicationRemote.cxx:981
 TApplicationRemote.cxx:982
 TApplicationRemote.cxx:983
 TApplicationRemote.cxx:984
 TApplicationRemote.cxx:985
 TApplicationRemote.cxx:986
 TApplicationRemote.cxx:987
 TApplicationRemote.cxx:988
 TApplicationRemote.cxx:989
 TApplicationRemote.cxx:990
 TApplicationRemote.cxx:991
 TApplicationRemote.cxx:992
 TApplicationRemote.cxx:993
 TApplicationRemote.cxx:994
 TApplicationRemote.cxx:995
 TApplicationRemote.cxx:996
 TApplicationRemote.cxx:997
 TApplicationRemote.cxx:998
 TApplicationRemote.cxx:999
 TApplicationRemote.cxx:1000
 TApplicationRemote.cxx:1001
 TApplicationRemote.cxx:1002
 TApplicationRemote.cxx:1003
 TApplicationRemote.cxx:1004
 TApplicationRemote.cxx:1005
 TApplicationRemote.cxx:1006
 TApplicationRemote.cxx:1007
 TApplicationRemote.cxx:1008
 TApplicationRemote.cxx:1009
 TApplicationRemote.cxx:1010
 TApplicationRemote.cxx:1011
 TApplicationRemote.cxx:1012
 TApplicationRemote.cxx:1013
 TApplicationRemote.cxx:1014
 TApplicationRemote.cxx:1015
 TApplicationRemote.cxx:1016
 TApplicationRemote.cxx:1017
 TApplicationRemote.cxx:1018
 TApplicationRemote.cxx:1019
 TApplicationRemote.cxx:1020
 TApplicationRemote.cxx:1021
 TApplicationRemote.cxx:1022
 TApplicationRemote.cxx:1023
 TApplicationRemote.cxx:1024
 TApplicationRemote.cxx:1025
 TApplicationRemote.cxx:1026
 TApplicationRemote.cxx:1027
 TApplicationRemote.cxx:1028
 TApplicationRemote.cxx:1029
 TApplicationRemote.cxx:1030
 TApplicationRemote.cxx:1031
 TApplicationRemote.cxx:1032
 TApplicationRemote.cxx:1033
 TApplicationRemote.cxx:1034
 TApplicationRemote.cxx:1035
 TApplicationRemote.cxx:1036
 TApplicationRemote.cxx:1037
 TApplicationRemote.cxx:1038
 TApplicationRemote.cxx:1039
 TApplicationRemote.cxx:1040
 TApplicationRemote.cxx:1041
 TApplicationRemote.cxx:1042
 TApplicationRemote.cxx:1043
 TApplicationRemote.cxx:1044
 TApplicationRemote.cxx:1045
 TApplicationRemote.cxx:1046
 TApplicationRemote.cxx:1047
 TApplicationRemote.cxx:1048
 TApplicationRemote.cxx:1049
 TApplicationRemote.cxx:1050
 TApplicationRemote.cxx:1051
 TApplicationRemote.cxx:1052
 TApplicationRemote.cxx:1053
 TApplicationRemote.cxx:1054
 TApplicationRemote.cxx:1055
 TApplicationRemote.cxx:1056
 TApplicationRemote.cxx:1057
 TApplicationRemote.cxx:1058