ROOT logo
// @(#)root/net:$Id$
// Author: Adrien Devresse and Tigran Mkrtchyan

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

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TDavixFile                                                           //
//                                                                      //
// A TDavixFile is like a normal TFile except that it uses              //
// libdavix to read/write remote files.                                 //
// It supports HTTP and HTTPS in a number of dialects and options       //
//  e.g. S3 is one of them                                              //
// Other caracteristics come from the full support of Davix,            //
//  e.g. full redirection support in any circumstance                   //
//                                                                      //
// Authors:     Adrien Devresse (CERN IT/SDC)                           //
//              Tigran Mkrtchyan (DESY)                                 //
//                                                                      //
// Checks and ROOT5 porting:                                            //
//              Fabrizio Furano (CERN IT/SDC)                           //
//                                                                      //
// September 2013                                                       //
//                                                                      //
//////////////////////////////////////////////////////////////////////////


#include "TDavixFile.h"
#include "TROOT.h"
#include "TSocket.h"
#include "Bytes.h"
#include "TError.h"
#include "TSystem.h"
#include "TEnv.h"
#include "TBase64.h"
#include "TVirtualPerfStats.h"
#include "TDavixFileInternal.h"
#include "TSocket.h"

#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <davix.hpp>
#include <sstream>
#include <string>
#include <cstring>


static const std::string VERSION = "0.2.0";

static const std::string gUserAgent = "ROOT/" + std::string(gROOT->GetVersion()) +
" TDavixFile/" + VERSION + " davix/" + Davix::version();

// The prefix that is used to find the variables in the gEnv
#define ENVPFX "Davix."

ClassImp(TDavixFile)

using namespace Davix;

const char* grid_mode_opt = "grid_mode=yes";
const char* ca_check_opt = "ca_check=no";
const char* s3_seckey_opt = "s3seckey=";
const char* s3_acckey_opt = "s3acckey=";
const char* open_mode_read = "READ";
const char* open_mode_create = "CREATE";
const char* open_mode_new = "NEW";
const char* open_mode_update = "UPDATE";

static TMutex createLock;
static Context* davix_context_s = NULL;


//____________________________________________________________________________
bool isno(const char *str)
{
   if (!str) return false;

   if (!strcmp(str, "n") || !strcmp(str, "no") || !strcmp(str, "0") || !strcmp(str, "false")) return true;

   return false;
}

//____________________________________________________________________________
int configure_open_flag(const std::string &str, int old_flag)
{
   if (strcasecmp(str.c_str(), open_mode_read) == 0)
      old_flag |= O_RDONLY;
   if ((strcasecmp(str.c_str(), open_mode_create) == 0)
         || (strcasecmp(str.c_str(), open_mode_new) == 0)) {
      old_flag |= (O_CREAT | O_WRONLY | O_TRUNC);
   }
   if ((strcasecmp(str.c_str(), open_mode_update) == 0)) {
      old_flag |= (O_RDWR);
   }
   return old_flag;
}

//____________________________________________________________________________
static void ConfigureDavixLogLevel()
{
   Int_t log_level = (gEnv) ? gEnv->GetValue("Davix.Debug", 0) : 0;

   switch (log_level) {
      case 0:
         davix_set_log_level(0);
         break;
      case 1:
         davix_set_log_level(DAVIX_LOG_WARNING);
         break;
      case 2:
         davix_set_log_level(DAVIX_LOG_VERBOSE);
         break;
      case 3:
         davix_set_log_level(DAVIX_LOG_DEBUG);
         break;
      default:
         davix_set_log_level(DAVIX_LOG_ALL);
         break;
   }
}


///////////////////////////////////////////////////////////////////
// Authn implementation, Locate and get VOMS cred if exist

//____________________________________________________________________________
static void TDavixFile_http_get_ucert(std::string &ucert, std::string &ukey)
{
   char default_proxy[64];
   const char *genvvar = 0, *genvvar1 = 0;
   // The gEnv has higher priority, let's look for a proxy cert
   genvvar = gEnv->GetValue("Davix.GSI.UserProxy", (const char *) NULL);
   if (genvvar) {
      ucert = ukey = genvvar;
      if (gDebug > 0)
         Info("TDavixFile_http_get_ucert", "Found proxy in gEnv");
      return;
   }

   // Try explicit environment for proxy
   if (getenv("X509_USER_PROXY")) {
      if (gDebug > 0)
         Info("TDavixFile_http_get_ucert", "Found proxy in X509_USER_PROXY");
      ucert = ukey = getenv("X509_USER_PROXY");
      return;
   }

   // Try with default location
   snprintf(default_proxy, sizeof(default_proxy), "/tmp/x509up_u%d",
            geteuid());

   if (access(default_proxy, R_OK) == 0) {
      if (gDebug > 0)
         Info("TDavixFile_http_get_ucert", "Found proxy in /tmp");
      ucert = ukey = default_proxy;
      return;
   }

   // It seems we got no proxy, let's try to gather the keys
   genvvar = gEnv->GetValue("Davix.GSI.UserCert", (const char *) NULL);
   genvvar1 = gEnv->GetValue("Davix.GSI.UserKey", (const char *) NULL);
   if (genvvar || genvvar1) {
      if (gDebug > 0)
         Info("TDavixFile_http_get_ucert", "Found cert and key in gEnv");

      ucert = genvvar;
      ukey = genvvar1;
      return;
   }

   // try with X509_* environment
   if (getenv("X509_USER_CERT"))
      ucert = getenv("X509_USER_CERT");
   if (getenv("X509_USER_KEY"))
      ukey = getenv("X509_USER_KEY");

   if ((ucert.size() > 0) || (ukey.size() > 0)) {
      if (gDebug > 0)
         Info("TDavixFile_http_get_ucert", "Found cert and key in gEnv");
   }
   return;
}

//____________________________________________________________________________
static int TDavixFile_http_authn_cert_X509(void *userdata, const Davix::SessionInfo &info,
      Davix::X509Credential *cert, Davix::DavixError **err)
{
   (void) userdata; // keep quiete compilation warnings
   (void) info;
   std::string ucert, ukey;
   TDavixFile_http_get_ucert(ucert, ukey);

   if (ucert.empty() || ukey.empty()) {
      Davix::DavixError::setupError(err, "TDavixFile",
                                    Davix::StatusCode::AuthentificationError,
                                    "Could not set the user's proxy or certificate");
      return -1;
   }
   return cert->loadFromFilePEM(ukey, ucert, "", err);
}

/////////////////////////////////////////////////////////////////////////////////////////////


//____________________________________________________________________________
TDavixFileInternal::~TDavixFileInternal()
{
   delete davixPosix;
   delete davixParam;
}

//____________________________________________________________________________
Context *TDavixFileInternal::getDavixInstance()
{
   if (davix_context_s == NULL) {
      TLockGuard guard(&createLock);
      if (davix_context_s == NULL) {
         davix_context_s = new Context();
      }
   }
   return davix_context_s;
}

//____________________________________________________________________________
Davix_fd *TDavixFileInternal::Open()
{
   DavixError *davixErr = NULL;
   Davix_fd *fd = davixPosix->open(davixParam, fUrl.GetUrl(), oflags, &davixErr);
   if (fd == NULL) {
      Error("DavixOpen", "can not open file with davix: %s (%d)",
            davixErr->getErrMsg().c_str(), davixErr->getStatus());
      DavixError::clearError(&davixErr);
   } else {
      // setup ROOT style read
      davixPosix->fadvise(fd, 0, 300, Davix::AdviseRandom);
   }

   return fd;
}

//____________________________________________________________________________
void TDavixFileInternal::Close()
{
   DavixError *davixErr = NULL;
   if (davixFd != NULL && davixPosix->close(davixFd, &davixErr)) {
      Error("DavixClose", "can not to close file with davix: %s (%d)",
            davixErr->getErrMsg().c_str(), davixErr->getStatus());
      DavixError::clearError(&davixErr);
   }
}

//____________________________________________________________________________
void TDavixFileInternal::enableGridMode()
{
   const char *env_var = NULL;

   if (gDebug > 1)
      Info("enableGridMode", " grid mode enabled !");

   if( ( env_var = getenv("X509_CERT_DIR")) == NULL){
      env_var= "/etc/grid-security/certificates/";
   }
   davixParam->addCertificateAuthorityPath(env_var);
   if (gDebug > 0)
      Info("enableGridMode", "Adding CAdir %s", env_var);
}

//____________________________________________________________________________
void TDavixFileInternal::setS3Auth(const std::string &key, const std::string &token)
{
   if (gDebug > 1)
      Info("setS3Auth", " Aws S3 tokens configured");
   davixParam->setAwsAuthorizationKeys(key, token);
   davixParam->setProtocol(RequestProtocol::AwsS3);
}

//____________________________________________________________________________
void TDavixFileInternal::parseConfig()
{
   const char *env_var = NULL, *env_var2 = NULL;
   // default opts
   davixParam->setTransparentRedirectionSupport(true);
   davixParam->setClientCertCallbackX509(&TDavixFile_http_authn_cert_X509, NULL);

   // setup CADIR
   env_var = gEnv->GetValue("Davix.GSI.CAdir", (const char *) NULL);
   if (env_var) {
      davixParam->addCertificateAuthorityPath(env_var);
      if (gDebug > 0)
         Info("parseConfig", "Add CAdir: %s", env_var);
   }
   // CA Check
   bool ca_check_local = !isno(gEnv->GetValue("Davix.GSI.CACheck", (const char *)"y"));
   davixParam->setSSLCAcheck(ca_check_local);
   if (gDebug > 0)
      Info("parseConfig", "Setting CAcheck to %s", ((ca_check_local) ? ("true") : ("false")));

   // S3 Auth
   if (((env_var = gEnv->GetValue("Davix.S3.SecretKey", getenv("S3_SECRET_KEY"))) != NULL)
         && ((env_var2 = gEnv->GetValue("Davix.S3.AccessKey", getenv("S3_ACCESS_KEY"))) != NULL)) {
      Info("parseConfig", "Setting S3 SecretKey and AccessKey. Access Key : %s ", env_var2);
      davixParam->setAwsAuthorizationKeys(env_var, env_var2);
   }

   env_var = gEnv->GetValue("Davix.GSI.GridMode", (const char *)"y");
   if (!isno(env_var))
      enableGridMode();
}

//____________________________________________________________________________
void TDavixFileInternal::parseParams(Option_t *option)
{
   // intput params
   std::stringstream ss(option);
   std::string item;
   std::vector<std::string> parsed_options;
   // parameters
   std::string s3seckey, s3acckey;

   while (std::getline(ss, item, ' ')) {
      parsed_options.push_back(item);
   }

   for (std::vector<std::string>::iterator it = parsed_options.begin(); it < parsed_options.end(); ++it) {
      // grid mode option
      if ((strcasecmp(it->c_str(), grid_mode_opt)) == 0) {
         enableGridMode();
      }
      // ca check option
      if ((strcasecmp(it->c_str(), ca_check_opt)) == 0) {
         davixParam->setSSLCAcheck(false);
      }
      // s3 sec key
      if (strncasecmp(it->c_str(), s3_seckey_opt, strlen(s3_seckey_opt)) == 0) {
         s3seckey = std::string(it->c_str() + strlen(s3_seckey_opt));
      }
      // s3 access key
      if (strncasecmp(it->c_str(), s3_acckey_opt, strlen(s3_acckey_opt)) == 0) {
         s3acckey = std::string(it->c_str() + strlen(s3_acckey_opt));
      }
      // open mods
      oflags = configure_open_flag(*it, oflags);
   }

   if (s3seckey.size() > 0) {
      setS3Auth(s3seckey, s3acckey);
   }

   if (oflags == 0) // default open mode
      oflags = O_RDONLY;
}

//____________________________________________________________________________
void TDavixFileInternal::init()
{
   davixPosix = new DavPosix(davixContext);
   davixParam = new RequestParams();
   davixParam->setUserAgent(gUserAgent);
   ConfigureDavixLogLevel();
   parseConfig();
   parseParams(opt);
}

//____________________________________________________________________________
Int_t TDavixFileInternal::DavixStat(const char *url, struct stat *st)
{
   DavixError *davixErr = NULL;

   if (davixPosix->stat(davixParam, url, st, &davixErr) < 0) {

      Error("DavixStat", "can not stat the file with davix: %s (%d)",
            davixErr->getErrMsg().c_str(), davixErr->getStatus());
      DavixError::clearError(&davixErr);
      return 0;
   }
   return 1;
}

/////////////////////////////////////////////////////////////////////////////////////////////

//______________________________________________________________________________
TDavixFile::TDavixFile(const char *url, Option_t *opt, const char *ftitle, Int_t compress) : TFile(url, "WEB"),
   d_ptr(new TDavixFileInternal(fUrl, opt))
{
   (void) ftitle;
   (void) compress;
   Init(kFALSE);
}

//______________________________________________________________________________
TDavixFile::~TDavixFile()
{
   d_ptr->Close();
   delete d_ptr;
}

//______________________________________________________________________________
void TDavixFile::Init(Bool_t init)
{
   (void) init;
   //initialize davix   
   d_ptr->init();
   // pre-open file
   if ((d_ptr->getDavixFileInstance()) == NULL){
         MakeZombie();
         gDirectory = gROOT;
         return;
   }
   TFile::Init(kFALSE);
   fOffset = 0;
   fD = -2; // so TFile::IsOpen() will return true when in TFile::~TFi */
}

//______________________________________________________________________________
void TDavixFile::Seek(Long64_t offset, ERelativeTo pos)
{
   // Set position from where to start reading.

   TLockGuard guard(&(d_ptr->positionLock));
   switch (pos) {
      case kBeg:
         fOffset = offset + fArchiveOffset;
         break;
      case kCur:
         fOffset += offset;
         break;
      case kEnd:
         // this option is not used currently in the ROOT code
         if (fArchiveOffset)
            Error("Seek", "seeking from end in archive is not (yet) supported");
         fOffset = fEND - offset; // is fEND really EOF or logical EOF?
         break;
   }

   if (gDebug > 1)
      Info("Seek", " move cursor to %lld"
           , fOffset);
}

//______________________________________________________________________________
Bool_t TDavixFile::ReadBuffer(char *buf, Int_t len)
{
   // Read specified byte range from remote file via HTTP.
   // Returns kTRUE in case of error.
   TLockGuard guard(&(d_ptr->positionLock));
   Davix_fd *fd;
   if ((fd = d_ptr->getDavixFileInstance()) == NULL)
      return kTRUE;
   Long64_t ret = DavixReadBuffer(fd, buf, len);
   if (ret < 0)
      return kTRUE;

   if (gDebug > 1)
      Info("ReadBuffer", "%lld bytes of data read sequentially"
           " (%d requested)", ret, len);

   return kFALSE;
}

//______________________________________________________________________________
Bool_t TDavixFile::ReadBuffer(char *buf, Long64_t pos, Int_t len)
{

   Davix_fd *fd;
   if ((fd = d_ptr->getDavixFileInstance()) == NULL)
      return kTRUE;

   Long64_t ret = DavixPReadBuffer(fd, buf, pos, len);
   if (ret < 0)
      return kTRUE;


   if (gDebug > 1)
      Info("ReadBuffer", "%lld bytes of data read from offset"
           " %lld (%d requested)", ret, pos, len);
   return kFALSE;
}

//____________________________________________________________________________
Bool_t TDavixFile::ReadBufferAsync(Long64_t offs, Int_t len)
{

   Davix_fd *fd;
   if ((fd = d_ptr->getDavixFileInstance()) == NULL)
      return kFALSE;

   d_ptr->davixPosix->fadvise(fd, static_cast<dav_off_t>(offs), static_cast<dav_size_t>(len), Davix::AdviseRandom);

   if (gDebug > 1)
      Info("ReadBufferAsync", "%d bytes of data prefected from offset"
           " %lld ",  len, offs);
   return kFALSE;
}

//______________________________________________________________________________
Bool_t TDavixFile::ReadBuffers(char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
{
   Davix_fd *fd;
   if ((fd = d_ptr->getDavixFileInstance()) == NULL)
      return kTRUE;

   Long64_t ret = DavixReadBuffers(fd, buf, pos, len, nbuf);
   if (ret < 0)
      return kTRUE;

   if (gDebug > 1)
      Info("ReadBuffers", "%lld bytes of data read from a list of %d buffers",
           ret, nbuf);

   return kFALSE;
}

//_____________________________________________________________________________
Bool_t TDavixFile::WriteBuffer(const char *buf, Int_t len)
{

   Davix_fd *fd;
   if ((fd = d_ptr->getDavixFileInstance()) == NULL)
      return kTRUE;

   Long64_t ret = DavixWriteBuffer(fd, buf, len);
   if (ret < 0)
      return kTRUE;

   if (gDebug > 1)
      Info("WriteBuffer", "%lld bytes of data write"
           " %d requested", ret, len);
   return kFALSE;
}

//____________________________________________________________________________
void TDavixFile::setCACheck(Bool_t check)
{
   d_ptr->davixParam->setSSLCAcheck((bool)check);
}

//____________________________________________________________________________
void TDavixFile::enableGridMode()
{
   d_ptr->enableGridMode();
}

//____________________________________________________________________________
bool TDavixFileInternal::isMyDird(void *fd)
{
   TLockGuard l(&(openLock));
   std::vector<void *>::iterator f = std::find(dirdVec.begin(), dirdVec.end(), fd);
   return (f != dirdVec.end());
}

//____________________________________________________________________________
void TDavixFileInternal::addDird(void *fd)
{
   TLockGuard l(&(openLock));
   dirdVec.push_back(fd);
}

//____________________________________________________________________________
void TDavixFileInternal::removeDird(void *fd)
{
   TLockGuard l(&(openLock));
   std::vector<void *>::iterator f = std::find(dirdVec.begin(), dirdVec.end(), fd);
   if (f != dirdVec.end())
      dirdVec.erase(f);
}


//______________________________________________________________________________
Long64_t TDavixFile::GetSize() const
{
   struct stat st;
   Int_t ret = d_ptr->DavixStat(fUrl.GetUrl(), &st);
   if (ret) {
      if (gDebug > 1)
         Info("GetSize", "file size requested:  %lld", (Long64_t)st.st_size);
      return st.st_size;
   }
   return -1;
}

//______________________________________________________________________________
Double_t TDavixFile::eventStart()
{
   if (gPerfStats)
      return TTimeStamp();
   return 0;
}

//______________________________________________________________________________
void TDavixFile::eventStop(Double_t t_start, Long64_t len)
{
   // set TFile state info
   fBytesRead += len;
   fReadCalls += 1;

   if (gPerfStats)
      gPerfStats->FileReadEvent(this, (Int_t) len, t_start);
}

//____________________________________________________________________________
Long64_t TDavixFile::DavixReadBuffer(Davix_fd *fd, char *buf, Int_t len)
{
   DavixError *davixErr = NULL;
   Double_t start_time = eventStart();

   Long64_t ret = d_ptr->davixPosix->pread(fd, buf, len, fOffset, &davixErr);
   if (ret < 0) {
      Error("DavixReadBuffer", "can not read data with davix: %s (%d)",
            davixErr->getErrMsg().c_str(), davixErr->getStatus());
      DavixError::clearError(&davixErr);
   } else {
      fOffset += ret;
      eventStop(start_time, ret);
   }

   return ret;
}

//____________________________________________________________________________
Long64_t TDavixFile::DavixWriteBuffer(Davix_fd *fd, const char *buf, Int_t len)
{
   DavixError *davixErr = NULL;
   Double_t start_time = eventStart();

   Long64_t ret = d_ptr->davixPosix->pwrite(fd, buf, len, fOffset, &davixErr);
   if (ret < 0) {
      Error("DavixWriteBuffer", "can not write data with davix: %s (%d)",
            davixErr->getErrMsg().c_str(), davixErr->getStatus());
      DavixError::clearError(&davixErr);
   } else {
      fOffset += ret;
      eventStop(start_time, ret);
   }

   return ret;
}

//____________________________________________________________________________
Long64_t TDavixFile::DavixPReadBuffer(Davix_fd *fd, char *buf, Long64_t pos, Int_t len)
{
   DavixError *davixErr = NULL;
   Double_t start_time = eventStart();

   Long64_t ret = d_ptr->davixPosix->pread(fd, buf, len, pos, &davixErr);
   if (ret < 0) {
      Error("DavixPReadBuffer", "can not read data with davix: %s (%d)",
            davixErr->getErrMsg().c_str(), davixErr->getStatus());
      DavixError::clearError(&davixErr);
   } else {
      eventStop(start_time, ret);
   }

   return ret;
}

//____________________________________________________________________________
Long64_t TDavixFile::DavixReadBuffers(Davix_fd *fd, char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
{
   DavixError *davixErr = NULL;
   Double_t start_time = eventStart();
   DavIOVecInput in[nbuf];
   DavIOVecOuput out[nbuf];

   int lastPos = 0;
   for (Int_t i = 0; i < nbuf; ++i) {
      in[i].diov_buffer = &buf[lastPos];
      in[i].diov_offset = pos[i];
      in[i].diov_size = len[i];
      lastPos += len[i];
   }

   Long64_t ret = d_ptr->davixPosix->preadVec(fd, in, out, nbuf, &davixErr);
   if (ret < 0) {
      Error("DavixReadBuffers", "can not read data with davix: %s (%d)",
            davixErr->getErrMsg().c_str(), davixErr->getStatus());
      DavixError::clearError(&davixErr);
   } else {
      eventStop(start_time, ret);
   }

   return ret;
}

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