From 73da28fad158aef707be89a40a286ae71b6042cb Mon Sep 17 00:00:00 2001
From: Victor Kotlyar <Victor.Kotlyar@cern.ch>
Date: Wed, 31 Aug 2016 16:22:53 +0200
Subject: [PATCH] Fixed usage of cta::excepion instead of castor::exception.
 Removed unused files. Added missed unittests.

---
 common/Configuration.hpp                      |   4 +-
 common/ProcessCap.cpp                         | 135 ---
 cta.spec.in                                   |   1 +
 tapeserver/castor/BaseCnvSvc.cpp              | 281 -------
 tapeserver/castor/IClientFactory.cpp          | 138 ----
 tapeserver/castor/client/BaseClient.cpp       | 775 ------------------
 .../castor/client/BasicResponseHandler.cpp    |  42 -
 .../castor/client/VectorResponseHandler.cpp   |  63 --
 .../castor/common/CastorConfiguration.hpp     |   4 +-
 tapeserver/castor/dlf/Dlf.cpp                 | 178 ----
 tapeserver/castor/io/io.hpp                   |  34 +-
 tapeserver/castor/mediachanger/CMakeLists.txt |   6 +
 .../castor/mediachanger/LibrarySlot.hpp       |   2 +-
 .../castor/mediachanger/LibrarySlotParser.hpp |   2 +-
 .../mediachanger/LibrarySlotParserTest.cpp    |   4 +-
 .../mediachanger/ManualLibrarySlotTest.cpp    |   4 +-
 .../castor/server/ListenerThreadPool.hpp      | 164 ----
 .../castor/server/MultiThreadedDaemon.hpp     | 169 ----
 .../castor/server/TCPListenerThreadPool.hpp   | 114 ---
 .../castor/server/UDPListenerThreadPool.hpp   |  91 --
 .../castor/server/metrics/Histogram.cpp       | 108 ---
 .../castor/server/metrics/Histogram.hpp       | 134 ---
 .../server/metrics/MetricsCollector.cpp       | 194 -----
 .../server/metrics/MetricsCollector.hpp       | 133 ---
 .../tape/tapeserver/daemon/CatalogueDrive.hpp |  22 +-
 .../daemon/CatalogueLabelSession.hpp          |   2 +-
 .../daemon/CatalogueTransferSession.hpp       |   2 +-
 .../tapeserver/daemon/DiskReadTaskTest.cpp    |   2 +-
 .../tape/tapeserver/file/CMakeLists.txt       |   5 +-
 .../tape/tapeserver/file/CryptoPPTest.cpp     |  14 +-
 tests/CMakeLists.txt                          |   1 +
 31 files changed, 60 insertions(+), 2768 deletions(-)
 delete mode 100644 common/ProcessCap.cpp
 delete mode 100644 tapeserver/castor/BaseCnvSvc.cpp
 delete mode 100644 tapeserver/castor/IClientFactory.cpp
 delete mode 100644 tapeserver/castor/client/BaseClient.cpp
 delete mode 100644 tapeserver/castor/client/BasicResponseHandler.cpp
 delete mode 100644 tapeserver/castor/client/VectorResponseHandler.cpp
 delete mode 100644 tapeserver/castor/dlf/Dlf.cpp
 delete mode 100644 tapeserver/castor/server/ListenerThreadPool.hpp
 delete mode 100644 tapeserver/castor/server/MultiThreadedDaemon.hpp
 delete mode 100644 tapeserver/castor/server/TCPListenerThreadPool.hpp
 delete mode 100644 tapeserver/castor/server/UDPListenerThreadPool.hpp
 delete mode 100644 tapeserver/castor/server/metrics/Histogram.cpp
 delete mode 100644 tapeserver/castor/server/metrics/Histogram.hpp
 delete mode 100644 tapeserver/castor/server/metrics/MetricsCollector.cpp
 delete mode 100644 tapeserver/castor/server/metrics/MetricsCollector.hpp

diff --git a/common/Configuration.hpp b/common/Configuration.hpp
index 109ad5ac06..524c01bad8 100644
--- a/common/Configuration.hpp
+++ b/common/Configuration.hpp
@@ -96,7 +96,7 @@ namespace cta { namespace common {
        * Retrieves a configuration entry.
        *
        * Besides other possible exceptions, this method throws a
-       * castor::exception::NoEntry exception if the specified configuration
+       * cta::exception::NoEntry exception if the specified configuration
        * entry is not in the configuration file.
        *
        * If this method is passed a logger object then this method will log the
@@ -172,7 +172,7 @@ namespace cta { namespace common {
        * Retrieves a configuration entry as an integer.
        *
        * Besides other possible exceptions, this method throws a
-       * castor::exception::NoEntry exception if the specified configuration
+       * cta::exception::NoEntry exception if the specified configuration
        * entry is not in the configuration file.
        *
        * @param category category of the configuration parameter
diff --git a/common/ProcessCap.cpp b/common/ProcessCap.cpp
deleted file mode 100644
index 7b19ef9a29..0000000000
--- a/common/ProcessCap.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * The CERN Tape Archive (CTA) project
- * Copyright (C) 2015  CERN
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "common/exception/Exception.hpp"
-#include "common/ProcessCap.hpp"
-#include "castor/server/SmartCap.hpp"
-#include "common/Utils.hpp"
-
-#include <errno.h>
-
-//------------------------------------------------------------------------------
-// destructor
-//------------------------------------------------------------------------------
-castor::server::ProcessCap::~ProcessCap()
-  throw() {
-}
-
-//------------------------------------------------------------------------------
-// getProcText
-//------------------------------------------------------------------------------
-std::string castor::server::ProcessCap::getProcText() {
-  try {
-    SmartCap cap(getProc());
-    return toText((cap_t)cap.get());
-  } catch(castor::exception::Exception &ne) {
-    castor::exception::Exception ex;
-    ex.getMessage() <<
-      "Failed to get text representation of the capabilities of the process: "
-      << ne.getMessage().str();
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// getProc
-//------------------------------------------------------------------------------
-cap_t castor::server::ProcessCap::getProc() {
-  cap_t cap = cap_get_proc();
-  if(NULL == cap) {
-    castor::exception::Exception ex;
-    ex.getMessage() <<
-      "Failed to get the capabilities of the process: " 
-        << cta::utils::errnoToString(errno);
-    throw ex;
-  }
-  return cap;
-}
-
-//------------------------------------------------------------------------------
-// toText
-//------------------------------------------------------------------------------
-std::string castor::server::ProcessCap::toText(
-  const cap_t cap) {
-  // Create a C++ string with the result of calling cap_to_text()
-  char *const text = cap_to_text(cap, NULL);
-  if(NULL == text) {
-    castor::exception::Exception ex;
-    ex.getMessage() <<
-      "Failed to create string representation of capability state: " 
-        << cta::utils::errnoToString(errno);
-    throw ex;
-  }
-  std::string result(text);
-
-  // Free the memory allocated by cap_to_text()
-  if(cap_free(text)) {
-    castor::exception::Exception ex;
-    ex.getMessage() <<
-      "Failed to free string representation of capability state: " 
-        << cta::utils::errnoToString(errno);
-    throw ex;
-  }
-
-  // Return the C++ string
-  return result;
-}
-
-//------------------------------------------------------------------------------
-// setProcText
-//------------------------------------------------------------------------------
-void castor::server::ProcessCap::setProcText(const std::string &text) {
-  try {
-    SmartCap cap(fromText(text));
-    setProc(cap.get());
-  } catch(castor::exception::Exception &ne) {
-    castor::exception::Exception ex;
-    ex.getMessage() <<
-      "Failed to set capabilities of process: " << ne.getMessage().str();
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// fromText
-//------------------------------------------------------------------------------
-cap_t castor::server::ProcessCap::fromText(const std::string &text) {
-  const cap_t cap = cap_from_text(text.c_str());
-  if(NULL == cap) {
-    castor::exception::Exception ex;
-    ex.getMessage() <<
-      "Failed to create capability state from string representation"
-      ": text='" << text << "': " << cta::utils::errnoToString(errno);
-    throw ex;
-  }
-
-  return cap;
-}
-
-//------------------------------------------------------------------------------
-// setProc
-//------------------------------------------------------------------------------
-void castor::server::ProcessCap::setProc(const cap_t cap) {
-  if(cap_set_proc(cap)) {
-    castor::exception::Exception ex;
-    ex.getMessage() <<
-      "Failed to set the capabilities of the process: " 
-        << cta::utils::errnoToString(errno);
-    throw ex;
-  }
-}
diff --git a/cta.spec.in b/cta.spec.in
index 105a3d7d89..4e862148da 100644
--- a/cta.spec.in
+++ b/cta.spec.in
@@ -232,6 +232,7 @@ Unit tests and system tests with virtual tape drives
 %attr(0755,root,root) %{_libdir}/libctatapeserverutilsunittests.so
 %attr(0755,root,root) %{_libdir}/libctautilsunittests.so
 %attr(0755,root,root) %{_libdir}/libctadaemonunittests.so
+%attr(0755,root,root) %{_libdir}/libctamediachangerunittests.so
 %attr(0755,root,root) %{_bindir}/cta-systemTests
 %attr(0755,root,root) %{_libdir}/libctadaemonunittests-multiprocess.so
 %attr(0644,root,root) %{_datadir}/%{name}-%{ctaVersion}/unittest/*.suppr
diff --git a/tapeserver/castor/BaseCnvSvc.cpp b/tapeserver/castor/BaseCnvSvc.cpp
deleted file mode 100644
index fc11c9ab8e..0000000000
--- a/tapeserver/castor/BaseCnvSvc.cpp
+++ /dev/null
@@ -1,281 +0,0 @@
-/******************************************************************************
- *
- * This file is part of the Castor project.
- * See http://castor.web.cern.ch/castor
- *
- * Copyright (C) 2003  CERN
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *
- *
- *
- * @author Castor Dev team, castor-dev@cern.ch
- *****************************************************************************/
-
-// Include Files
-#include <vector>
-#include <map>
-#include "castor/exception/Exception.hpp"
-
-// Local Includes
-#include "ICnvFactory.hpp"
-#include "BaseCnvSvc.hpp"
-#include "Converters.hpp"
-#include "IConverter.hpp"
-#include "IAddress.hpp"
-#include "IObject.hpp"
-
-// -----------------------------------------------------------------------
-// Constructor
-// -----------------------------------------------------------------------
-castor::BaseCnvSvc::BaseCnvSvc(const std::string name) :
-  BaseSvc(name) {}
-
-// -----------------------------------------------------------------------
-// Destructor
-// -----------------------------------------------------------------------
-castor::BaseCnvSvc::~BaseCnvSvc() throw() {
-  BaseCnvSvc::reset();
-}
-
-// -----------------------------------------------------------------------
-// reset
-// -----------------------------------------------------------------------
-void castor::BaseCnvSvc::reset() throw() {
-  // release all converters
-  std::map<unsigned int, IConverter*>::iterator it;
-  for (it = m_converters.begin(); it != m_converters.end(); it++) {
-    if (it->second != 0) {
-      delete it->second;
-    }
-  }
-  m_converters.clear();
-  // call parent's reset
-  BaseSvc::reset();
-}
-
-//-----------------------------------------------------------------------------
-// addAlias
-//-----------------------------------------------------------------------------
-void castor::BaseCnvSvc::addAlias(const unsigned int alias,
-                                  const unsigned int real) {
-  m_aliases[alias] = real;
-}
-
-//-----------------------------------------------------------------------------
-// removeAlias
-//-----------------------------------------------------------------------------
-void castor::BaseCnvSvc::removeAlias(const unsigned int id) {
-  m_aliases.erase(id);
-}
-
-//-----------------------------------------------------------------------------
-// converter
-//-----------------------------------------------------------------------------
-castor::IConverter* castor::BaseCnvSvc::converter
-(const unsigned int origObjType)
-   {
-  // First uses aliases
-  unsigned int objType = origObjType;
-  if (m_aliases.find(objType) != m_aliases.end()) {
-    objType = m_aliases[objType];
-  }
-  // check if we have one
-  IConverter* conv = m_converters[objType];
-  if (0 != conv) return conv;
-  // Try to find one
-  const castor::ICnvFactory* fac =
-    castor::Converters::instance()->cnvFactory(repType(), objType);
-  if (0 == fac) {
-    castor::exception::Exception e;
-    e.getMessage() << "No factory found for object type "
-                   << objType << " and representation type "
-                   << repType();
-    throw e;
-  }
-  m_converters[objType] = fac->instantiate(this);
-  if (0!= m_converters[objType]) return m_converters[objType];
-  // Throw an exception since we did not find any suitable converter
-  castor::exception::Exception e;
-  e.getMessage() << "No converter for object type "
-                 << objType << " and representation type "
-                 << repType();
-  throw e;
-}
-
-// -----------------------------------------------------------------------
-// createRep
-// -----------------------------------------------------------------------
-void castor::BaseCnvSvc::createRep(castor::IAddress* address,
-                                   castor::IObject* object,
-                                   bool endTransaction,
-                                   unsigned int type)
-   {
-  // If no object, nothing to create
-  if (0 != object) {
-    // Look for an adapted converter
-    // The converter is always valid if no exception is thrown
-    IConverter* conv = converter(object->type());
-    // convert
-    conv->createRep(address, object, endTransaction, type);
-  }
-}
-
-// -----------------------------------------------------------------------
-// bulkCreateRep
-// -----------------------------------------------------------------------
-void castor::BaseCnvSvc::bulkCreateRep(castor::IAddress* address,
-                                       std::vector<castor::IObject*> &objects,
-                                       bool endTransaction,
-                                       unsigned int type)
-   {
-  // If no object, nothing to create
-  if (objects.size() > 0) {
-    // Look for an adapted converter
-    // The converter is always valid if no exception is thrown
-    // Note that we assume that all objects have the same type
-    IConverter* conv = converter(objects[0]->type());
-    // convert
-    conv->bulkCreateRep(address, objects, endTransaction, type);
-  }
-}
-
-// -----------------------------------------------------------------------
-// updateRep
-// -----------------------------------------------------------------------
-void castor::BaseCnvSvc::updateRep(castor::IAddress* address,
-                                   castor::IObject* object,
-                                   bool endTransaction)
-   {
-  // If no object, nothing to update
-  if (0 != object) {
-    // Look for an adapted converter
-    // The converter is always valid if no exception is thrown
-    IConverter* conv = converter(object->type());
-    // convert
-    conv->updateRep(address, object, endTransaction);
-  }
-}
-
-// -----------------------------------------------------------------------
-// deleteRep
-// -----------------------------------------------------------------------
-void castor::BaseCnvSvc::deleteRep(castor::IAddress* address,
-                                   castor::IObject* object,
-                                   bool endTransaction)
-   {
-  // Look for an adapted converter
-  // The converter is always valid if no exception is thrown
-  IConverter* conv = converter(object->type());
-  // convert
-  conv->deleteRep(address, object, endTransaction);
-}
-
-// -----------------------------------------------------------------------
-// createObj
-// -----------------------------------------------------------------------
-castor::IObject* castor::BaseCnvSvc::createObj
-(castor::IAddress* address)
-   {
-  // Look for an adapted converter
-  // The converter is always valid if no exception is thrown
-  castor::IConverter* conv = converter(address->objType());
-  return conv->createObj(address);
-}
-
-// -----------------------------------------------------------------------
-// bulkCreateObj
-// -----------------------------------------------------------------------
-std::vector<castor::IObject*> castor::BaseCnvSvc::bulkCreateObj
-(castor::IAddress* address)
-   {
-  // Look for an adapted converter
-  // The converter is always valid if no exception is thrown
-  castor::IConverter* conv = converter(address->objType());
-  return conv->bulkCreateObj(address);
-}
-
-// -----------------------------------------------------------------------
-// updateObj
-// -----------------------------------------------------------------------
-void castor::BaseCnvSvc::updateObj(castor::IObject* object)
-   {
-  // Look for an adapted converter
-  // The converter is always valid if no exception is thrown
-  castor::IConverter* conv = converter(object->type());
-  return conv->updateObj(object);
-}
-
-//------------------------------------------------------------------------------
-// fillRep
-//------------------------------------------------------------------------------
-void castor::BaseCnvSvc::fillRep(castor::IAddress* address,
-                                 castor::IObject* object,
-                                 unsigned int type,
-                                 bool endTransaction)
-   {
-  // Look for an adapted converter
-  // The converter is always valid if no exception is thrown
-  castor::IConverter* conv = converter(object->type());
-  return conv->fillRep(address, object, type, endTransaction);
-}
-
-//------------------------------------------------------------------------------
-// fillObj
-//------------------------------------------------------------------------------
-void castor::BaseCnvSvc::fillObj(castor::IAddress* address,
-                                 castor::IObject* object,
-                                 unsigned int type,
-                                 bool endTransaction)
-   {
-  // Look for an adapted converter
-  // The converter is always valid if no exception is thrown
-  castor::IConverter* conv = converter(object->type());
-  return conv->fillObj(address, object, type, endTransaction);
-}
-
-// -----------------------------------------------------------------------
-// deleteRepByAddress
-// -----------------------------------------------------------------------
-void castor::BaseCnvSvc::deleteRepByAddress (castor::IAddress* address,
-                                             bool endTransaction)
-   {
-  castor::IObject* obj = createObj(address);
-  address->setObjType(obj->type());
-  deleteRep(address, obj, endTransaction);
-}
-
-//------------------------------------------------------------------------------
-// commit
-//------------------------------------------------------------------------------
-void castor::BaseCnvSvc::commit()
-   {
-  // Default implementation, does nothing.
-}
-
-//------------------------------------------------------------------------------
-// rollback
-//------------------------------------------------------------------------------
-void castor::BaseCnvSvc::rollback()
-   {
-  // Default implementation, does nothing.
-}
-
-//------------------------------------------------------------------------------
-// createStatement
-//------------------------------------------------------------------------------
-castor::db::IDbStatement* castor::BaseCnvSvc::createStatement(const std::string&)
-   {
-  // Default implementation, does nothing.
-  return 0;
-}
diff --git a/tapeserver/castor/IClientFactory.cpp b/tapeserver/castor/IClientFactory.cpp
deleted file mode 100644
index 3e4f651837..0000000000
--- a/tapeserver/castor/IClientFactory.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/******************************************************************************
- *
- * This file is part of the Castor project.
- * See http://castor.web.cern.ch/castor
- *
- * Copyright (C) 2003  CERN
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *
- * 
- *
- * @author Castor Dev team, castor-dev@cern.ch
- *****************************************************************************/
-
-// Include Files
-#include "castor/IClientFactory.hpp"
-#include "castor/rh/Client.hpp"
-#include "castor/IClient.hpp"
-#include "castor/Constants.hpp"
-#include "castor/exception/Exception.hpp"
-#include "castor/exception/InvalidArgument.hpp"
-#include <sstream>
-
-
-//------------------------------------------------------------------------------
-// client2String
-//------------------------------------------------------------------------------
-const std::string castor::IClientFactory::client2String
-(const castor::IClient &cl)
-   {
-  switch (cl.type()) {
-  case castor::OBJ_Client :
-    {
-      const castor::rh::Client *c =
-        dynamic_cast<const castor::rh::Client*>(&cl);
-      std::ostringstream res;
-      res << cl.type() << ":"
-          << ((c->ipAddress() & 0xFF000000) >> 24) << "."
-          << ((c->ipAddress() & 0x00FF0000) >> 16) << "."
-          << ((c->ipAddress() & 0x0000FF00) >> 8) << "."
-          << ((c->ipAddress() & 0x000000FF))
-          << ":" << c->port();
-      return res.str();
-    }
-  default:
-    castor::exception::InvalidArgument e;
-    e.getMessage() << "Unknown Client type "
-                   << castor::ObjectsIdStrings[cl.type()]
-                   << std::endl
-                   << "Cannot convert to string";
-    throw e;
-  }
-}
-
-//------------------------------------------------------------------------------
-// string2Client
-//------------------------------------------------------------------------------
-castor::IClient* castor::IClientFactory::string2Client(const std::string &st)
-   {
-  std::istringstream in(st);
-  unsigned int type;
-  in >> type;
-  if (in.good()) { 
-    switch (type) {
-    case castor::OBJ_Client :
-      {
-        char c = 0;
-        in >> c;
-        if (c == ':') {
-          unsigned short a[4];
-          for (int i = 0; i < 4; i++) {
-            in >> a[i];
-            if (a[i] > 255) {
-              castor::exception::InvalidArgument e;
-              e.getMessage() << "Invalid IP address in Client string : \""
-                             << st << "\"" << std::endl
-                             << "Cannot convert string to Client";
-              throw e;
-            }
-            if (i < 3) {
-              c = 0;
-              in >> c;
-              if (c != '.') {
-                castor::exception::InvalidArgument e;
-                e.getMessage() << "Invalid IP address in Client string : \""
-                               << st << "\"" << std::endl
-                               << "Cannot convert string to Client";
-                throw e;
-              }
-            }
-          }
-          c = 0;
-          in >> c;
-          if (c == ':') {
-            unsigned short port = 0;
-            in >> port;
-            if (in) {
-              castor::rh::Client *res = new castor::rh::Client();
-              unsigned long ip = a[0];
-              ip <<= 8;
-              ip += a[1];
-              ip <<= 8;
-              ip += a[2];
-              ip <<= 8;
-              ip += a[3];
-              res->setIpAddress(ip);
-              res->setPort(port);
-              return res;
-            }
-          }
-        }
-      }
-      break;
-    default:
-      castor::exception::InvalidArgument e;
-      e.getMessage() << "Unknown type " << type
-                     << " for a client" << std::endl
-                     << "Cannot convert string to IClient";
-      throw e;
-    }
-    
-  }
-  castor::exception::InvalidArgument e;
-  e.getMessage() << "Unable to parse Client string : \""
-                 << st << "\"" << std::endl
-                 << "Cannot create Object";
-  throw e;
-}
diff --git a/tapeserver/castor/client/BaseClient.cpp b/tapeserver/castor/client/BaseClient.cpp
deleted file mode 100644
index 5cd9117f19..0000000000
--- a/tapeserver/castor/client/BaseClient.cpp
+++ /dev/null
@@ -1,775 +0,0 @@
-/******************************************************************************
- *
- * This file is part of the Castor project.
- * See http://castor.web.cern.ch/castor
- *
- * Copyright (C) 2003  CERN
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * @(#)BaseClient.cpp,v 1.37 $Release$ 2006/02/16 15:56:58 sponcec3
- *
- * A base class for all castor clients. Implements many
- * useful and common parts for all clients.
- *
- * @author Castor Dev team, castor-dev@cern.ch
- *****************************************************************************/
-
-// Include Files
-#include <errno.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <Cpwd.h>
-#include "patchlevel.h"
-#include "castor/io/ClientSocket.hpp"
-#include "castor/io/AuthClientSocket.hpp"
-#include "castor/io/ServerSocket.hpp"
-#include "castor/io/AuthServerSocket.hpp"
-#include "castor/Constants.hpp"
-#include "castor/System.hpp"
-#include "castor/IClient.hpp"
-#include "castor/IObject.hpp"
-#include "castor/MessageAck.hpp"
-#include "castor/rh/Client.hpp"
-#include "castor/rh/Response.hpp"
-
-#include "castor/stager/StageFileQueryRequest.hpp"
-#include "castor/stager/Request.hpp"
-#include "castor/stager/FileRequest.hpp"
-
-#include "castor/client/IResponseHandler.hpp"
-#include "castor/exception/Exception.hpp"
-#include "castor/exception/Communication.hpp"
-#include "castor/exception/InvalidArgument.hpp"
-#include "stager_client_api_common.hpp"
-
-
-extern "C" {
-#include <Cgetopt.h>
-#include <common.h>
-}
-
-// Local includes
-#include "BaseClient.hpp"
-
-//------------------------------------------------------------------------------
-// String constants
-//------------------------------------------------------------------------------
-const char *castor::client::HOST_ENV = "STAGE_HOST";
-const char *castor::client::PORT_ENV = "STAGE_PORT";
-const char *castor::client::SEC_PORT_ENV = "STAGE_SEC_PORT";
-const char *castor::client::CATEGORY_CONF = "STAGER";
-const char *castor::client::HOST_CONF = "HOST";
-const char *castor::client::PORT_CONF = "PORT";
-const char *castor::client::SEC_PORT_CONF = "SEC_PORT";
-const char *castor::client::STAGE_EUID = "STAGE_EUID";
-const char *castor::client::STAGE_EGID = "STAGE_EGID";
-const char *castor::client::CLIENT_CONF = "CLIENT";
-const char *castor::client::LOWPORT_CONF = "LOWPORT";
-const char *castor::client::HIGHPORT_CONF = "HIGHPORT";
-const char *castor::client::SEC_MECH_ENV = "CSEC_MECH"; // Security protocol ID, KRB5
-const char *castor::client::SECURITY_ENV = "SECURE_CASTOR"; // Security enable
-const char *castor::client::SECURITY_CONF = "SECURE_CASTOR";
-
-
-//------------------------------------------------------------------------------
-// Numeric constants
-//------------------------------------------------------------------------------
-const int castor::client::LOW_CLIENT_PORT_RANGE = 30000;
-const int castor::client::HIGH_CLIENT_PORT_RANGE = 30100;
-
-//------------------------------------------------------------------------------
-// Timing utility
-//------------------------------------------------------------------------------
-#ifdef SIXMONTHS
-#undef SIXMONTHS
-#endif
-#define SIXMONTHS (6*30*24*60*60)
-
-namespace {
-static char strftime_format_sixmonthsold[] = "%b %e %Y";
-static char strftime_format[] = "%b %e %H:%M:%S";
-
-void BaseClient_util_time(time_t then, char *timestr) {
-  time_t this_time = time(NULL);
-  struct tm tmstruc;
-  struct tm *tp;
-
-  localtime_r(&(then),&tmstruc);
-  tp = &tmstruc;
-  if ((this_time >= then) && ((this_time - then) > SIXMONTHS)) {
-    // Too much in past
-    strftime(timestr,64,strftime_format_sixmonthsold,tp);
-  } else if ((this_time < then) && ((then - this_time) > SIXMONTHS)) {
-    // Too much in future...!
-    strftime(timestr,64,strftime_format_sixmonthsold,tp);
-  } else {
-    strftime(timestr,64,strftime_format,tp);
-  }
-}
-}
-
-//------------------------------------------------------------------------------
-// constructor
-//------------------------------------------------------------------------------
-castor::client::BaseClient::BaseClient
-(int acceptTimeout, int transferTimeout) throw() :
-  BaseObject(),
-  m_rhPort(-1),
-  m_callbackSocket(0),
-  m_requestId(""),
-  m_acceptTimeout(acceptTimeout),
-  m_transferTimeout(transferTimeout),
-  m_hasAuthorizationId(false),
-  m_authUid(0),
-  m_authGid(0),
-  m_hasSecAuthorization(false),
-  m_voname(0),
-  m_nbfqan(0),
-  m_fqan(0),
-  m_sendAckTime(0),
-  m_nfds(0) {
-  memset(m_fds, 0, sizeof(m_fds));
-  setAuthorization();
-  // Check timeout value. Max value * 1000 should fit into an int as it will be
-  // used by poll that wants milliseconds. If the value is too big, it is
-  // translated into -1, i.e. infinity. Equally, any negative value is mapped to
-  // -1 as some OSs refuse any other negative value.
-  if (acceptTimeout > 2147483 || acceptTimeout < 0) {
-    m_acceptTimeout = -1;
-  }
-}
-
-//------------------------------------------------------------------------------
-// destructor
-//------------------------------------------------------------------------------
-castor::client::BaseClient::~BaseClient() throw() {
-  if (0 != m_callbackSocket) delete m_callbackSocket;
-}
-
-
-//------------------------------------------------------------------------------
-// createClient
-//------------------------------------------------------------------------------
-castor::IClient* castor::client::BaseClient::createClient()
-   {
-  // if no callbackSocket
-  if (0 == m_callbackSocket) {
-    castor::exception::Exception ex;
-    ex.getMessage() << "No call back socket available";
-    throw ex;
-  }
-  // build client
-  unsigned short port;
-  unsigned long ip;
-  m_callbackSocket->getPortIp(port, ip);
-  castor::rh::Client *result = new castor::rh::Client();
-  result->setIpAddress(ip);
-  result->setPort(port);
-  result->setVersion(MAJORVERSION*1000000+MINORVERSION*10000+MAJORRELEASE*100+MINORRELEASE);
-  return result;
-}
-
-//------------------------------------------------------------------------------
-// internalSendRequest
-//------------------------------------------------------------------------------
-std::string castor::client::BaseClient::internalSendRequest
-(castor::stager::Request& request)
-   {
-  std::string requestId;
-
-  // The service class has been previously resolved, attach it to the request
-  request.setSvcClassName(m_rhSvcClass);
-
-  // Tracing the submit time
-  char timestr[64];
-  castor::io::ClientSocket* s;
-  time_t now = time(NULL);
-  BaseClient_util_time(now, timestr);
-  stage_trace(3, "%s (%u) Sending request", timestr, now);
-
-  // Prepare the timing information
-  clock_t startTime;
-  struct tms buf;
-  startTime = times(&buf);
-
-  // Create a socket
-  if (m_hasSecAuthorization) {
-    s = new castor::io::AuthClientSocket(m_rhPort, m_rhHost);
-    // If the context cannot be established there will be an exception thrown.
-  } else {
-    s = new castor::io::ClientSocket(m_rhPort, m_rhHost);
-  }
-
-  try {
-    // Set the timeout for the socket, if not defined DEFAULT_NETTIMEOUT will
-    // be used
-    if (m_transferTimeout > 0) {
-      s->setTimeout(m_transferTimeout);
-    }
-    s->connect();
-
-    // Send the request
-    s->sendObject(request);
-
-    // Wait for acknowledgment
-    IObject* obj = s->readObject();
-    castor::MessageAck* ack =
-      dynamic_cast<castor::MessageAck*>(obj);
-    if (0 == ack) {
-      castor::exception::InvalidArgument e;
-      e.getMessage() << "No Acknowledgement from the Server";
-      throw e;
-    }
-    requestId = ack->requestId();
-    setRequestId(requestId);
-    if (!ack->status()) {
-      castor::exception::Exception e(ack->errorCode());
-      e.getMessage() << ack->errorMessage();
-      delete ack;
-      throw e;
-    }
-    delete ack;
-    m_sendAckTime = times(&buf);
-    stage_trace(3, "%s SND %.2f s to send the request",
-                requestId.c_str(),
-                ((float)(m_sendAckTime - startTime)) / ((float)sysconf(_SC_CLK_TCK)));
-    delete s;
-    return requestId;
-  }
-  catch (castor::exception::Exception& e) {
-    // forward any exception after closing the socket
-    delete s;
-    throw e;
-  }
-}
-
-//------------------------------------------------------------------------------
-// setRhPort
-//------------------------------------------------------------------------------
-void castor::client::BaseClient::setRhPort()
-   {
-  setRhPort(0);
-}
-
-void castor::client::BaseClient::setRhPort(int optPort)
-   {
-
-  if (optPort > 65535) {
-    castor::exception::Exception e(EINVAL);
-    e.getMessage() << "Invalid port value : " << optPort
-                   << ". Must be < 65535." << std::endl;
-    throw e;
-  }
-  if (optPort > 0) {
-    m_rhPort = optPort;
-  } else {
-    // Resolve RH port:
-    // if security mode is used get the RH Secure server port,
-    // the value can be given through the environment
-    // or in the castor.conf file. If none is given, default is used
-    char* port;
-    if (m_hasSecAuthorization) {
-      if ((port = getenv (castor::client::SEC_PORT_ENV)) != 0
-          || (port = getconfent((char *)castor::client::CATEGORY_CONF,
-                                (char *)castor::client::SEC_PORT_CONF, 0)) != 0) {
-        m_rhPort = castor::System::porttoi(port);
-      } else {
-        m_rhPort = CSP_RHSERVER_SEC_PORT;
-      }
-    } else {
-      if ((port = getenv (castor::client::PORT_ENV)) != 0
-          || (port = getconfent((char *)castor::client::CATEGORY_CONF,
-                                (char *)castor::client::PORT_CONF, 0)) != 0) {
-        m_rhPort = castor::System::porttoi(port);
-      } else {
-        m_rhPort = CSP_RHSERVER_PORT;
-      }
-    }
-  }
-  stage_trace(3, "Looking up RH port - Using %d", m_rhPort);
-}
-
-//------------------------------------------------------------------------------
-// setRhHost
-//------------------------------------------------------------------------------
-void castor::client::BaseClient::setRhHost()
-   {
-  setRhHost("");
-}
-
-void castor::client::BaseClient::setRhHost(std::string optHost)
-   {
-  // RH server host. Can be passed given through the
-  // STAGER_HOST environment variable or in the castor.conf
-  // file as a STAGER/HOST entry
-  if (optHost.compare("")) {
-    m_rhHost = optHost;
-  } else {
-    char* host;
-    if ((host = getenv (castor::client::HOST_ENV)) != 0
-        || (host = getconfent((char *)castor::client::CATEGORY_CONF,
-                              (char *)castor::client::HOST_CONF,0)) != 0) {
-      m_rhHost = host;
-    } else {
-      // could not find a value for STAGER_HOST. Giving up
-      castor::exception::Exception e(SENOSHOST);
-      e.getMessage() << "Unable to find a value for STAGE_HOST.\n"
-                     << "Please check castor.conf and/or your environment" << std::endl;
-      throw e;
-    }
-  }
-  stage_trace(3, "Looking up RH host - Using %s", m_rhHost.c_str());
-}
-
-//------------------------------------------------------------------------------
-// setRhSvcClass
-//------------------------------------------------------------------------------
-void castor::client::BaseClient::setRhSvcClass()
-   {
-  setRhSvcClass("");
-}
-
-void castor::client::BaseClient::setRhSvcClass(std::string optSvcClass)
-   {
-  // RH server host. Can be passed given through the
-  // RH_HOST environment variable or in the castor.conf
-  // file as a RH/HOST entry
-  if (optSvcClass.compare("")) {
-    m_rhSvcClass = optSvcClass;
-  } else {
-    char* svc;
-    if ((svc = getenv ("STAGE_SVCCLASS")) != 0
-        || (svc = getconfent("STAGER", "SVCCLASS",0)) != 0) {
-      m_rhSvcClass = svc;
-    } else {
-      m_rhSvcClass = "";
-    }
-  }
-  if (!m_rhSvcClass.empty()) {
-    stage_trace(3, "Looking up service class - Using %s", m_rhSvcClass.c_str());
-  }
-}
-
-
-//------------------------------------------------------------------------------
-// setOptions
-//------------------------------------------------------------------------------
-void castor::client::BaseClient::setOptions(struct stage_options* opts)
-   {
-  if (0 != opts) {
-    setRhHost(opts->stage_host);
-    setRhPort(opts->stage_port);
-    setRhSvcClass(opts->service_class);
-  } else {
-    setRhHost("");
-    setRhPort(0);
-    setRhSvcClass("");
-  }
-}
-
-//------------------------------------------------------------------------------
-// setRequestId
-//------------------------------------------------------------------------------
-void castor::client::BaseClient::setRequestId(std::string requestId) {
-  m_requestId = requestId;
-}
-
-//------------------------------------------------------------------------------
-// requestId
-//------------------------------------------------------------------------------
-std::string castor::client::BaseClient::requestId() {
-  return m_requestId;
-}
-
-//------------------------------------------------------------------------------
-// setAutorizationId
-//----------------------------------------------------------------------------
-void castor::client::BaseClient::setAuthorizationId()
-   {
-  if (stage_getid(&m_authUid, &m_authGid) < 0) {
-    castor::exception::Exception e(serrno);
-    e.getMessage() << "Error in stage_getid" << std::endl;
-    throw e;
-  } else {
-    m_hasAuthorizationId = true;
-  }
-}
-
-//------------------------------------------------------------------------------
-// setAuthorizationId
-//------------------------------------------------------------------------------
-void castor::client::BaseClient::setAuthorizationId(uid_t uid, gid_t gid) throw() {
-  m_authUid = uid;
-  m_authGid = gid;
-  m_hasAuthorizationId = true;
-}
-
-//------------------------------------------------------------------------------
-// setAuthorization
-//------------------------------------------------------------------------------
-void castor::client::BaseClient::setAuthorization()  {
-  char *security;
-  // Check if security env option is set.
-  if (((security = getenv (castor::client::SECURITY_ENV)) != 0 ||
-       (security = getconfent((char *)castor::client::CLIENT_CONF,
-                              (char *)castor::client::SECURITY_CONF,0)) != 0 ) &&
-      strcasecmp(security, "YES") == 0) {
-        m_Sec_mech = "KRB5";
-        m_hasSecAuthorization = true;
-        stage_trace(3, "Setting security mechanism: KRB5");
-      }
-}
-
-//------------------------------------------------------------------------------
-// createClientAndSend
-//------------------------------------------------------------------------------
-std::string castor::client::BaseClient::createClientAndSend
-(castor::stager::Request *req)
-   {
-  // builds the Client (uuid,guid,hostname,etc)
-  buildClient(req);
-
-  // sends the request
-  std::string requestId = internalSendRequest(*req);
-  return requestId;
-}
-
-//------------------------------------------------------------------------------
-// buildClient
-//------------------------------------------------------------------------------
-void castor::client::BaseClient::buildClient(castor::stager::Request* req)
-   {
-
-  // Uid
-  uid_t euid;
-  char *stgeuid = getenv(castor::client::STAGE_EUID);
-  if (0 != stgeuid) {
-    euid = atoi(stgeuid);
-  } else {
-    if (m_hasAuthorizationId) {
-      euid = m_authUid;
-    } else {
-      euid = geteuid();
-    }
-  }
-  stage_trace(3, "Setting euid: %d", euid);
-  req->setEuid(euid);
-
-  // GID
-  uid_t egid;
-  char *stgegid = getenv(castor::client::STAGE_EGID);
-  if (0 != stgegid) {
-    egid = atoi(stgegid);
-  } else {
-    if (m_hasAuthorizationId) {
-      egid = m_authGid;
-    } else {
-      egid = getegid();
-    }
-  }
-  stage_trace(3, "Setting egid: %d", egid);
-  req->setEgid(egid);
-
-  // Username
-  errno = 0;
-  struct passwd *pw = Cgetpwuid(euid);
-  if (0 == pw) {
-    castor::exception::Exception e(EINVAL);
-    e.getMessage() << "Unknown User" << std::endl;
-    throw e;
-  } else {
-    req->setUserName(pw->pw_name);
-  }
-
-  // Mask
-  mode_t mask = umask(0);
-  umask(mask);
-  req->setMask(mask);
-
-  // Pid
-  req->setPid(getpid());
-
-  // Machine
-  std::string hostName;
-
-  hostName  = castor::System::getHostName();
-  if (hostName == ""){
-    castor::exception::Exception e(errno);
-    e.getMessage() << "Could not get the localhost"
-                   <<  strerror(errno);
-    throw e;
-  }
-  stage_trace(3, "Localhost is: %s", hostName.c_str() );
-
-  req->setMachine(hostName);
-  if (m_rhHost == "") {
-    castor::exception::Exception e(errno);
-    e.getMessage() << "Could not get RH host name"
-                   <<  strerror(errno);
-    throw e;
-  }
-
-  // Create a socket for the callback
-  m_callbackSocket = new castor::io::ServerSocket(false);
-
-  // Get the port range to be used
-  int lowPort  = LOW_CLIENT_PORT_RANGE;
-  int highPort = HIGH_CLIENT_PORT_RANGE;
-  char* sport;
-  if ((sport = getconfent((char *)castor::client::CLIENT_CONF,
-                          (char *)castor::client::LOWPORT_CONF, 0)) != 0) {
-    lowPort = castor::System::porttoi(sport);
-  }
-  if ((sport = getconfent((char *)castor::client::CLIENT_CONF,
-                          (char *)castor::client::HIGHPORT_CONF, 0)) != 0) {
-    highPort = castor::System::porttoi(sport);
-  }
-
-  // Set the socket to non blocking
-  int rc;
-  int nonblocking = 1;
-  rc = ioctl(m_callbackSocket->socket(), FIONBIO, &nonblocking);
-  if (rc == -1) {
-    castor::exception::InvalidArgument e;
-    e.getMessage() << "Could not set socket asynchronous";
-    throw e;
-  }
-
-  // Bind the socket
-  m_callbackSocket->bind(lowPort, highPort);
-  m_callbackSocket->listen();
-  unsigned short port;
-  unsigned long ip;
-  m_callbackSocket->getPortIp(port, ip);
-  stage_trace(3, "Creating socket for castor callback - Using port %d", port);
-
-  // Add the listening socket to the pollfd structure
-  m_fds[0].fd = m_callbackSocket->socket();
-  m_fds[0].events = POLLIN;
-  m_nfds = 1;
-
-  // Set the Client
-  castor::IClient *cl = createClient();
-  req->setClient(cl);
-}
-
-//------------------------------------------------------------------------------
-// pollAnswersFromStager
-//------------------------------------------------------------------------------
-void castor::client::BaseClient::pollAnswersFromStager
-(castor::stager::Request* req, castor::client::IResponseHandler* rh)
-   {
-
-  // Check parameters
-  if ((req == NULL) || (req->client() == NULL)) {
-    castor::exception::Exception ex;
-    ex.getMessage() << "Passed Request is NULL" << std::endl;
-    throw ex;
-  }
-
-  // Determine the number of replies we expect to get from the stager. For
-  // requests which are subrequest orientated the responses may come from
-  // multiple stagers and be spread over time. As a consequence we should
-  // expect 1..N number of callbacks. For requests which are not subrequest
-  // orientated we expect one and only one callback/connection from the
-  // stager with all the responses.
-  unsigned int nbReplies = 1;
-  castor::stager::FileRequest *fr =
-    dynamic_cast<castor::stager::FileRequest *>(req);
-  if (fr != 0) {
-    nbReplies = fr->subRequests().size();
-    // special case when no subrequests. We still expect an answer
-    if (0 == nbReplies) nbReplies = 1;
-  }
-
-  stage_trace(3, "Waiting for callback from castor");
-
-  // Loop over the number of replies we expect to get from the stager, once we
-  // achieve the correct number of replies we can return control to the calling
-  // function.
-  unsigned int replies = 0;
-  unsigned int i, j;
-  bool complete = false;
-
-  do {
-
-    // Wait for a POLLIN event on the list of file descriptors
-    int rc = poll(m_fds, m_nfds, m_acceptTimeout * 1000);
-    if (rc == 0) {
-      castor::exception::Communication e(requestId(), SETIMEDOUT);
-      e.getMessage() << "Accept timeout";
-      throw e;
-    } else if (rc < 0) {
-      if (errno == EINTR) {
-        continue; // A signal was caught during poll()
-      }
-      castor::exception::Communication e(requestId(), errno);
-      e.getMessage() << "Poll error:" << strerror(errno);
-      throw e;
-    }
-
-    // Loop over the file descriptors
-    unsigned int nfds = m_nfds;
-    for (i = 0; i < nfds; i++) {
-      if (m_fds[i].revents == 0) {
-        continue;  // Nothing of interest
-      }
-      // Unexpected result?
-      if ((m_fds[i].revents & POLLIN) != POLLIN) {
-        castor::exception::Exception e(SEINTERNAL);
-        e.getMessage() << "Unexpected result from poll(): revents: "
-                       << m_fds[i].revents << " should be: POLLIN ("
-                       << POLLIN << ")";
-        throw e;
-      }
-      // Is the listening descriptor readable? If so, this indicates that there
-      // is a new incoming connection
-      if (m_fds[i].fd == m_callbackSocket->socket()) {
-
-        // Accept the incoming connection
-        castor::io::ServerSocket* socket = m_callbackSocket->accept();
-        socket->setTimeout(900);
-
-        // Log the ip address of the incoming connection
-        unsigned short port;
-        unsigned long ip;
-        socket->getPeerIp(port, ip);
-
-        std::ostringstream ipToStr;
-        ipToStr << ((ip & 0xFF000000) >> 24) << "."
-                << ((ip & 0x00FF0000) >> 16) << "."
-                << ((ip & 0x0000FF00) >> 8)  << "."
-                << ((ip & 0x000000FF));
-        struct tms buf;
-        clock_t endTime = times(&buf);
-        stage_trace(3, "%s CBK %.2f s before callback from %s was received",
-                    requestId().c_str(),
-                    ((float)(endTime - m_sendAckTime)) / ((float)sysconf(_SC_CLK_TCK)),
-                    ipToStr.str().c_str());
-
-        // Register the new file descriptor in the accepted connections list and
-        // the pollfd structure
-        m_connected.push_back(socket);
-        m_fds[m_nfds].fd = socket->socket();
-        m_fds[m_nfds].events = POLLIN;
-        m_fds[m_nfds].revents = 0;
-        m_nfds++;
-      } else {
-        // This is not the listening socket therefore we have new data to read.
-        // Locate the socket in the list of accepted connections
-        castor::io::ServerSocket* socket = 0;
-        for (j = 0; j < m_connected.size(); j++) {
-          if (m_fds[i].fd == m_connected[j]->socket()) {
-            socket = m_connected[j];
-            break;
-          }
-        }
-
-        // The socket was not found?
-        if (socket == 0) {
-          castor::exception::Exception e(SEINTERNAL);
-          e.getMessage() << "Unexpected exception caught, POLLIN event "
-                         << "received for unknown socket";
-          throw e;
-        }
-
-        // Read object from socket
-        IObject *obj = 0;
-        try {
-          obj = socket->readObject();
-        } catch (castor::exception::Exception& e) {
-          // Ignore "Connection closed by remote end" errors. This is just the
-          // request replier of the stager terminating the connection because it
-          // has nothing else to send.
-          if (e.code() == 1016) {
-            serrno = 0;    // Reset serrno to 0
-
-            // Remove the socket from the accepted connections list and set the
-            // file descriptor in the pollfd structures to -1. Later on the
-            // structure will be cleaned up
-            delete socket;
-            m_connected.erase(m_connected.begin() + j);
-            m_fds[i].fd = -1;
-            // If the number of replies is 1 and the connection has been closed
-            // then we are complete
-            if (nbReplies == 1) {
-              complete = true;
-            }
-            break;
-          }
-          throw e;
-        }
-
-        // Process the objects data
-        try {
-          if (obj->type() == OBJ_EndResponse) {
-            delete obj;
-            continue; // Ignored since 2.1.7-7+
-          }
-
-          // Cast response into Response*
-          castor::rh::Response *res =
-            dynamic_cast<castor::rh::Response *>(obj);
-          if (res == 0) {
-            castor::exception::Communication e(requestId(), SEINTERNAL);
-            e.getMessage() << "Received bad response type :" << obj->type();
-            throw e;
-          }
-
-          // Check that the request id sent is what we expected
-          if ((res->reqAssociated().length() != 0) &&
-              (res->reqAssociated() != requestId())) {
-            delete obj;
-            continue;
-          }
-
-          // Handle the response
-          rh->handleResponse(*res);
-
-          // Cleanup for next iteration
-          delete obj;
-          replies++;
-        } catch (castor::exception::Exception& e) {
-          delete obj;
-          throw e;
-        }
-      }
-    }
-
-    // Compress the pollfd structure removing entries where the file descriptor
-    // is negative. We do not need to move back the events and revents fields
-    // because the events will always be POLLIN in this case, and revents is
-    // output.
-    for (i = 0; i < m_nfds; i++) {
-      if (m_fds[i].fd == -1) {
-        for (j = i; j < m_nfds; j++) {
-          m_fds[j].fd = m_fds[j + 1].fd;
-        }
-        m_nfds--;
-      }
-    }
-  } while (((replies < nbReplies) && (nbReplies != 1)) ||
-          ((nbReplies == 1) && !complete));
-
-  // Free resources
-  for (i = 0; i < m_connected.size(); i++) {
-    if (m_connected[i] != 0) delete m_connected[i];
-  }
-  m_connected.clear();
-
-  // If we've got this far it means that we haven't thrown an exception and
-  // that all responses have been received so we terminate the response handler
-  rh->terminate();
-}
diff --git a/tapeserver/castor/client/BasicResponseHandler.cpp b/tapeserver/castor/client/BasicResponseHandler.cpp
deleted file mode 100644
index 97403ea233..0000000000
--- a/tapeserver/castor/client/BasicResponseHandler.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/******************************************************************************
- *
- * This file is part of the Castor project.
- * See http://castor.web.cern.ch/castor
- *
- * Copyright (C) 2003  CERN
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *
- *
- *
- * @author Castor Dev team, castor-dev@cern.ch
- *****************************************************************************/
-
-// Include Files
-#include "castor/client/BasicResponseHandler.hpp"
-#include "castor/rh/BasicResponse.hpp"
-
-//------------------------------------------------------------------------------
-// handleResponse
-//------------------------------------------------------------------------------
-void castor::client::BasicResponseHandler::handleResponse
-(castor::rh::Response& r)
-   {
-  castor::rh::BasicResponse *resp =
-    dynamic_cast<castor::rh::BasicResponse*>(&r);
-  if (resp->errorCode() > 0) {
-    castor::exception::Exception e(resp->errorCode());
-    e.getMessage() << resp->errorMessage();
-    throw e;
-  }
-}
diff --git a/tapeserver/castor/client/VectorResponseHandler.cpp b/tapeserver/castor/client/VectorResponseHandler.cpp
deleted file mode 100644
index 371d805281..0000000000
--- a/tapeserver/castor/client/VectorResponseHandler.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/******************************************************************************
- *
- * This file is part of the Castor project.
- * See http://castor.web.cern.ch/castor
- *
- * Copyright (C) 2003  CERN
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *
- * A multi-file Response Handler for command line clients
- *
- * @author Castor Dev team, castor-dev@cern.ch
- *****************************************************************************/
-
-// Include Files
-#include "errno.h"
-#include "VectorResponseHandler.hpp"
-#include "castor/rh/Response.hpp"
-#include "castor/exception/Exception.hpp"
-#include <castor/IObject.hpp>
-#include <vector>
-
-
-//------------------------------------------------------------------------------
-// Constructor
-//------------------------------------------------------------------------------
-castor::client::VectorResponseHandler::VectorResponseHandler
-(std::vector<castor::rh::Response *> *vector)
-  {
-  if (0 == vector) {
-    castor::exception::Exception e(EINVAL);
-    e.getMessage() << "Null pointer passed to VectorResponseHandler constructor";
-    throw e;
-  }
-  m_responses = vector;
-}
-
-//------------------------------------------------------------------------------
-// handleResponse
-//------------------------------------------------------------------------------
-void castor::client::VectorResponseHandler::handleResponse
-(castor::rh::Response& r)
-   {
-  castor::IObject *obj = r.clone();
-  castor::rh::Response *resp = dynamic_cast<castor::rh::Response *>(obj);
-  if (0 == resp) {
-    delete obj;
-    castor::exception::Exception e(EINVAL);
-    e.getMessage() << "Could not cast down to Response*";
-    throw e;
-  }
-  m_responses->push_back(resp);
-}
diff --git a/tapeserver/castor/common/CastorConfiguration.hpp b/tapeserver/castor/common/CastorConfiguration.hpp
index 5291cf592c..db49a41e91 100644
--- a/tapeserver/castor/common/CastorConfiguration.hpp
+++ b/tapeserver/castor/common/CastorConfiguration.hpp
@@ -107,7 +107,7 @@ namespace castor {
        * Retrieves a configuration entry.
        *
        * Besides other possible exceptions, this method throws a
-       * castor::exception::NoEntry exception if the specified configuration
+       * cta::exception::NoEntry exception if the specified configuration
        * entry is not in the configuration file.
        *
        * If this method is passed a logger object then this method will log the
@@ -183,7 +183,7 @@ namespace castor {
        * Retrieves a configuration entry as an integer.
        *
        * Besides other possible exceptions, this method throws a
-       * castor::exception::NoEntry exception if the specified configuration
+       * cta::exception::NoEntry exception if the specified configuration
        * entry is not in the configuration file.
        *
        * @param category category of the configuration parameter
diff --git a/tapeserver/castor/dlf/Dlf.cpp b/tapeserver/castor/dlf/Dlf.cpp
deleted file mode 100644
index ad753af645..0000000000
--- a/tapeserver/castor/dlf/Dlf.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-/******************************************************************************
- *
- * This file is part of the Castor project.
- * See http://castor.web.cern.ch/castor
- *
- * Copyright (C) 2003  CERN
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * @(#)Dlf.cpp,v 1.1 $Release$ 2005/04/05 11:51:33 sponcec3
- *
- * C++ interface to DLF
- *
- * @author Castor Dev team, castor-dev@cern.ch
- *****************************************************************************/
-
-// Include Files
-#include "castor/dlf/Dlf.hpp"
-#include "castor/exception/Exception.hpp"
-
-#include <errno.h>
-
-//-----------------------------------------------------------------------------
-// dlf_getPendingMessages
-//-----------------------------------------------------------------------------
-std::vector<std::pair<int, castor::dlf::Message*> >&
-castor::dlf::dlf_getPendingMessages () throw() {
-  static PendingMessagesVector pendingMessages;
-  return pendingMessages;
-}
-
-//-----------------------------------------------------------------------------
-// dlf_init
-//-----------------------------------------------------------------------------
-void castor::dlf::dlf_init
-(const char* facilityName, castor::dlf::Message messages[])
-   {
-  // Initialise the DLF interface
-  if (::dlf_init(facilityName) != 0) {
-    castor::exception::Exception ex;
-    ex.getMessage() << "Unable to initialize DLF: " << sstrerror(errno);
-    throw ex;
-  }
-  // Register the facility's messages with the interface. We do this even
-  // if the interface fails to initialisation as it is used for local
-  // logging
-  dlf_addMessages(0, messages);
-  // Also register the pending messages
-  for (std::vector<std::pair<int, Message*> >::iterator it =
-         dlf_getPendingMessages().begin();
-       it != dlf_getPendingMessages().end();
-       it++) {
-    dlf_addMessages(it->first, it->second);
-    delete[](it->second);
-    it->second = NULL;
-  }
-  dlf_getPendingMessages().clear();
-}
-
-//-----------------------------------------------------------------------------
-// dlf_addMessages
-//-----------------------------------------------------------------------------
-void castor::dlf::dlf_addMessages (int offset, Message messages[])
-  throw() {
-  if (::dlf_isinitialized()) {
-    int i = 0;
-    while (messages[i].number >= 0) {
-      ::dlf_regtext(offset + messages[i].number,
-                    messages[i].text.c_str());
-      i++;
-    }
-  } else {
-    // replicate message array
-    int len = 0;
-    while (messages[len].number >= 0) {
-      len++;
-    }
-    Message* lmessages = new Message[len+1];
-    lmessages[len].number = -1;
-    for (int i = 0; i < len; i++) {
-      lmessages[i].number = messages[i].number;
-      lmessages[i].text = messages[i].text;
-    }
-    // and store it for further usage when DLF will be initialized
-    dlf_getPendingMessages().push_back(std::pair<int, Message*>(offset, lmessages));
-  }
-}
-
-//-----------------------------------------------------------------------------
-// dlf_writep
-// wrapper of the dlf writep that compounds the Cns_fileid struct
-//-----------------------------------------------------------------------------
-void castor::dlf::dlf_writep
-(Cuuid_t uuid,
- int severity,
- int message_no,
- u_signed64 fileId,
- std::string nsHost,
- int numparams,
- castor::dlf::Param params[])
-  throw() {
-
-  struct Cns_fileid ns_invariant;
-  ns_invariant.fileid = fileId;
-  strncpy(ns_invariant.server, nsHost.c_str(), sizeof(ns_invariant.server) - 1);
-
-  castor::dlf::dlf_writep(uuid, severity, message_no, numparams, params, &ns_invariant);
-}
-
-//-----------------------------------------------------------------------------
-// dlf_writep
-//-----------------------------------------------------------------------------
-void castor::dlf::dlf_writep
-(Cuuid_t uuid,
- int severity,
- int message_no,
- int numparams,
- castor::dlf::Param params[],
- struct Cns_fileid *ns_invariant) throw() {
-  // Place holder for the C version of the parameters
-  // dlf_write_param_t cparams[numparams]; // Doesn't work on windows compiler!!!
-  dlf_write_param_t* cparams = new dlf_write_param_t[numparams];
-  // Translate parameters from C++ to C
-  for (int i = 0; i < numparams; i++) {
-    cparams[i] = params[i].cParam();
-  }
-  ::dlf_writep(uuid, severity, message_no,
-               ns_invariant, numparams, cparams);
-  delete[] cparams;
-}
-
-//-----------------------------------------------------------------------------
-// dlf_writepc
-//-----------------------------------------------------------------------------
-void castor::dlf::dlf_writepc
-(const char *file,
- const int line,
- const char *function,
- Cuuid_t uuid,
- int severity,
- int message_no,
- int numparams,
- castor::dlf::Param params[],
- struct Cns_fileid *ns_invariant) throw() {
-  // Place holder for the C version of the parameters, allocate 3 more
-  // parameters for the context parameters: file, line and function
-  const int numcontextparams = 3;
-  const int numcparams = numparams + numcontextparams;
-  dlf_write_param_t* cparams = new dlf_write_param_t[numcparams];
-
-  // Fill the context parameters: file, line and function
-  cparams[0].name             = (char*)"File";
-  cparams[0].type             = DLF_MSG_PARAM_STR;
-  cparams[0].value.par_string = (char *)file;
-  cparams[1].name             = (char*)"Line";
-  cparams[1].type             = DLF_MSG_PARAM_INT;
-  cparams[1].value.par_int    = line;
-  cparams[2].name             = (char*)"Function";
-  cparams[2].type             = DLF_MSG_PARAM_STR;
-  cparams[2].value.par_string = (char*)function;
-
-  // Translate parameters from C++ to C
-  for (int i = 0; i < numparams; i++) {
-    cparams[i+numcontextparams] = params[i].cParam();
-  }
-  ::dlf_writep(uuid, severity, message_no,
-               ns_invariant, numcparams, cparams);
-  delete[] cparams;
-}
diff --git a/tapeserver/castor/io/io.hpp b/tapeserver/castor/io/io.hpp
index 34af4174e4..00beae0d41 100644
--- a/tapeserver/castor/io/io.hpp
+++ b/tapeserver/castor/io/io.hpp
@@ -58,10 +58,10 @@ namespace io     {
  * listening port will accept connections on any of the hosts incomming
  * interfaces.
  *
- * This method raises a castor::exception::InvalidArgument exception if one or
+ * This method raises a cta::exception::InvalidArgument exception if one or
  * more of its input parameters are invalid.
  *
- * This method raises a castor::exception::NoPortInRange exception if the
+ * This method raises a cta::exception::NoPortInRange exception if the
  * specified port is not free.
  *
  * @param port The port number.
@@ -77,10 +77,10 @@ int createListenerSock(const unsigned short port)
  * listening port will accept connections on any of the hosts incomming
  * interfaces.
  *
- * This method raises a castor::exception::InvalidArgument exception if one or
+ * This method raises a cta::exception::InvalidArgument exception if one or
  * more of its input parameters are invalid.
  *
- * This method raises a castor::exception::NoPortInRange exception if it cannot
+ * This method raises a cta::exception::NoPortInRange exception if it cannot
  * find a free port to bind to within the specified range.
  *
  * @param lowPort    The inclusive low port of the port number range.  This
@@ -102,10 +102,10 @@ int createListenerSock(
  *
  * This method creates the socket, binds it and marks it as a listener.
  *
- * This method raises a castor::exception::InvalidArgument exception if one or
+ * This method raises a cta::exception::InvalidArgument exception if one or
  * more of its input parameters are invalid.
  *
- * This method raises a castor::exception::NoPortInRange exception if it cannot
+ * This method raises a cta::exception::NoPortInRange exception if it cannot
  * find a free port to bind to within the specified range.
  *
  * @param addr       The IP address as a string in dotted quad notation.
@@ -128,10 +128,10 @@ int createListenerSock(
  * Creates a listener socket with a port number within the specified range.
  * This method creates the socket, binds it and marks it as a listener.
  *
- * This method raises a castor::exception::InvalidArgument exception if one or
+ * This method raises a cta::exception::InvalidArgument exception if one or
  * more of its input parameters are invalid.
  *
- * This method raises a castor::exception::NoPortInRange exception if it cannot
+ * This method raises a cta::exception::NoPortInRange exception if it cannot
  * find a free port to bind to within the specified range.
  *
  * @param addr       The IP address.
@@ -159,10 +159,10 @@ int createListenerSock(
  * listening port will accept connections on any of the hosts incomming
  * interfaces.
  *
- * This method raises a castor::exception::InvalidArgument exception if one or
+ * This method raises a cta::exception::InvalidArgument exception if one or
  * more of its input parameters are invalid.
  *
- * This method raises a castor::exception::NoPortInRange exception if the
+ * This method raises a cta::exception::NoPortInRange exception if the
  * specified port is not free.
  *
  * @param port The port number.
@@ -187,15 +187,15 @@ int acceptConnection(const int listenSockFd)
  * socket descriptor of the newly created and connected socket.
  *
  * This method accepts a timeout parameter.  If the timeout is exceeded, then
- * this method raises a castor::exception::TimeOut exception.  If this method
+ * this method raises a cta::exception::TimeOut exception.  If this method
  * is interrupted, then this method raises a
- * castor::exception::AcceptConnectionInterrupted exception which gives the
+ * cta::exception::AcceptConnectionInterrupted exception which gives the
  * number of remaining seconds when the interrupt occured.  All other errors
  * result in a cta::exception::Exception being raised.  Note that both
- * castor::exception::TimeOut and castor::exception::AcceptConnectionInterrupted
+ * cta::exception::TimeOut and cta::exception::AcceptConnectionInterrupted
  * inherit from cta::exception::Exception so callers of the this method must
- * catch castor::exception::TimeOut and
- * castor::exception::AcceptConnectionInterrupted before catching
+ * catch cta::exception::TimeOut and
+ * cta::exception::AcceptConnectionInterrupted before catching
  * cta::exception::Exception.
  *
  * @param listenSockFd The file descriptor of the listener socket.
@@ -346,7 +346,7 @@ void writeBytes(
  * Creates the specified socket and uses it to connect to the specified
  * address within the constraint of the specified timeout.
  *
- * This method throws a castor::exception::TimeOut exception if a timeout
+ * This method throws a cta::exception::TimeOut exception if a timeout
  * occurs.
  *
  * This method throws a cta::exception::Exception exception if an error
@@ -369,7 +369,7 @@ int connectWithTimeout(
  * Creates the specified socket and uses it to connect to the specified
  * address within the constraint of the specified timeout.
  *
- * This method throws a castor::exception::TimeOut exception if a timeout
+ * This method throws a cta::exception::TimeOut exception if a timeout
  * occurs.
  *
  * This method throws a cta::exception::Exception exception if an error
diff --git a/tapeserver/castor/mediachanger/CMakeLists.txt b/tapeserver/castor/mediachanger/CMakeLists.txt
index acee5cddad..b2bc597c0e 100644
--- a/tapeserver/castor/mediachanger/CMakeLists.txt
+++ b/tapeserver/castor/mediachanger/CMakeLists.txt
@@ -78,5 +78,11 @@ target_link_libraries (cta-mediachanger-dismount
   ctamessages
   ctautils
   ctaio)
+
+add_library (ctamediachangerunittests SHARED
+  LibrarySlotParserTest.cpp
+  ManualLibrarySlotTest.cpp)
+
+install(TARGETS ctamediachangerunittests DESTINATION usr/${CMAKE_INSTALL_LIBDIR})
 install (TARGETS cta-mediachanger-dismount DESTINATION /usr/bin)
 install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/cta-mediachanger-dismount.1cta DESTINATION /usr/share/man/man1)
diff --git a/tapeserver/castor/mediachanger/LibrarySlot.hpp b/tapeserver/castor/mediachanger/LibrarySlot.hpp
index f39bee6ea9..09f55ef084 100644
--- a/tapeserver/castor/mediachanger/LibrarySlot.hpp
+++ b/tapeserver/castor/mediachanger/LibrarySlot.hpp
@@ -88,7 +88,7 @@ private:
    * Thread safe method that returns the type of the tape-library to which the
    * specified library slot refers.
    *
-   * This function throws a castor::exception::Exception if the type of the
+   * This function throws a cta::exception::Exception if the type of the
    * tape-library cannot be determined.
    *
    * @param slot The tape-library slot.
diff --git a/tapeserver/castor/mediachanger/LibrarySlotParser.hpp b/tapeserver/castor/mediachanger/LibrarySlotParser.hpp
index 88ee05fbaa..995333b7a9 100644
--- a/tapeserver/castor/mediachanger/LibrarySlotParser.hpp
+++ b/tapeserver/castor/mediachanger/LibrarySlotParser.hpp
@@ -62,7 +62,7 @@ private:
    * This permits a two step parsing strategy where the user can be given more
    * detailed syntax errors where necessary.
    *
-   * This method throws a castor::exception::Exception if the type of the
+   * This method throws a cta::exception::Exception if the type of the
    * library slot cannot be determined.
    *
    * @param str The string representation of the tape library slot.
diff --git a/tapeserver/castor/mediachanger/LibrarySlotParserTest.cpp b/tapeserver/castor/mediachanger/LibrarySlotParserTest.cpp
index fad543b6ec..0595469007 100644
--- a/tapeserver/castor/mediachanger/LibrarySlotParserTest.cpp
+++ b/tapeserver/castor/mediachanger/LibrarySlotParserTest.cpp
@@ -21,7 +21,7 @@
  * @author Castor Dev team, castor-dev@cern.ch
  *****************************************************************************/
 
-#include "castor/exception/Exception.hpp"
+#include "common/exception/Exception.hpp"
 #include "castor/mediachanger/LibrarySlotParser.hpp"
 
 #include <gtest/gtest.h>
@@ -71,7 +71,7 @@ TEST_F(castor_mediachanger_LibrarySlotParserTest, nonsense) {
 
   std::unique_ptr<LibrarySlot> slot;
   ASSERT_THROW(slot.reset(LibrarySlotParser::parse("nonsense")),
-    castor::exception::Exception);
+    cta::exception::Exception);
 }
 
 } // namespace unitTests
diff --git a/tapeserver/castor/mediachanger/ManualLibrarySlotTest.cpp b/tapeserver/castor/mediachanger/ManualLibrarySlotTest.cpp
index ea9dc81d98..e20fec8bf8 100644
--- a/tapeserver/castor/mediachanger/ManualLibrarySlotTest.cpp
+++ b/tapeserver/castor/mediachanger/ManualLibrarySlotTest.cpp
@@ -21,7 +21,7 @@
  * @author Castor Dev team, castor-dev@cern.ch
  *****************************************************************************/
 
-#include "castor/exception/Exception.hpp"
+#include "common/exception/Exception.hpp"
 #include "castor/mediachanger/ManualLibrarySlot.hpp"
 
 #include <gtest/gtest.h>
@@ -54,7 +54,7 @@ TEST_F(castor_mediachanger_ManualLibrarySlotTest, notmanual) {
 
   std::unique_ptr<ManualLibrarySlot> slot;
   ASSERT_THROW(slot.reset(new ManualLibrarySlot("notmanual")),
-    castor::exception::Exception);
+    cta::exception::Exception);
 }
 
 TEST_F(castor_mediachanger_ManualLibrarySlotTest, clone) {
diff --git a/tapeserver/castor/server/ListenerThreadPool.hpp b/tapeserver/castor/server/ListenerThreadPool.hpp
deleted file mode 100644
index 89923c554c..0000000000
--- a/tapeserver/castor/server/ListenerThreadPool.hpp
+++ /dev/null
@@ -1,164 +0,0 @@
-/******************************************************************************
- *
- * This file is part of the Castor project.
- * See http://castor.web.cern.ch/castor
- *
- * Copyright (C) 2003  CERN
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *
- * Abstract class defining a listener thread pool
- *
- * @author Castor Dev team, castor-dev@cern.ch
- *****************************************************************************/
-
-#pragma once
-
-#include <iostream>
-#include <string>
-#include "castor/server/DynamicThreadPool.hpp"
-#include "castor/exception/Exception.hpp"
-#include "castor/io/AbstractSocket.hpp"
-
-namespace castor {
-
- namespace server {
-
-  /**
-   * Listener thread pool: allows processing upcoming
-   * requests in dedicated threads.
-   */
-  class ListenerThreadPool : public DynamicThreadPool {
-
-  /// This is the producer thread for this pool
-  friend class ListenerProducerThread;
-
-  public:
-
-    /**
-     * Constructor for a listener with a fixed number of threads.
-     * @param poolName, thread as in BaseThreadPool
-     * @param listenPort the port to be used by the listening socket.
-     * @param waitIfBusy true to wait on dispatching to a worker thread
-     * even if all threads are busy, as opposed to reject the connection
-     * @param nbThreads number of threads in the pool
-     */
-    ListenerThreadPool(const std::string poolName, castor::server::IThread* thread,
-                       unsigned int listenPort,
-                       bool waitIfBusy,
-                       unsigned int nbThreads = DEFAULT_THREAD_NUMBER)
-      ;
-
-    /**
-     * Constructor for a listener with a dynamic number of threads.
-     * @param poolName, thread as in BaseThreadPool
-     * @param listenPort the port to be used by the listening socket.
-     * @param waitIfBusy true to wait on dispatching to a worker thread
-     * even if all threads are busy, as opposed to reject the connection
-     * @param initThreads, maxThreads, threshold, maxTasks as in DynamicThreadPool
-     */
-    ListenerThreadPool(const std::string poolName, castor::server::IThread* thread,
-                       unsigned int listenPort,
-                       bool waitIfBusy,
-                       unsigned int initThreads,
-                       unsigned int maxThreads,
-                       unsigned int threshold = DEFAULT_THRESHOLD,
-                       unsigned int maxTasks  = DEFAULT_MAXTASKS)      
-      ;
-                       
-    /**
-     * Destructor
-     */
-    virtual ~ListenerThreadPool() throw();
-    
-    /**
-     * Starts the pool and the listener loop to accept connections.
-     */
-    virtual void run() ;
-
-    /**
-     * Shutdowns the pool by calling the ancestor's shutdown
-     * and by closing the listening socket.
-     * @return true if the pool has stopped.
-     */
-    virtual bool shutdown(bool wait = true) throw();
-      
-    /**
-     * Sets the port on which this ThreadPool should listen
-     */
-    inline void setPort(unsigned int port)
-      { m_port = port; }
-	
-  protected:
-  
-    /**
-     * Binds a socket to the given port. Children classes must implement
-     * this method according to the type of socket they need to use.
-     * @throw castor::exception::Exception if the port is busy.
-     */
-    virtual void bind()  = 0;
-
-    /**
-     * The listening loop implementation for this Listener.
-     * Children classes must override this method to provide different listener behaviors;
-     * it is expected that this method implements a never-ending loop.
-     */
-    virtual void listenLoop() = 0;
-
-    /**
-     * Forks and assigns work to a thread from the pool.
-     * @param param user parameter passed to thread->run().
-     */
-    virtual void threadAssign(void* param);
-    
-    /**
-     * Terminates the work to be done when the thread pool is exhausted.
-     * By default, this does nothing, but on a TCP-based pool it is adviced to
-     * at least close the connection to the client.
-     * @param param user parameter that would have been passed to a thread
-     */
-    virtual void terminate(void*) throw() {};
-
-    /// The socket used to accept connections
-    castor::io::AbstractSocket* m_sock;
-    
-    /// TCP port to listen for
-    unsigned int m_port;
-
-    /**
-     * Flag to decide whether to wait for dispatching in case
-     * no thread is idle as opposed to reject the incoming connection
-     */
-    bool m_waitIfBusy;
-    
-  };
-  
-  /// A simple producer helper class, which runs the listening loop
-  class ListenerProducerThread : public IThread {
-
-    /// Empty init
-    virtual void init() {};
-
-    /// Runs the listening loop of the pool passed as argument
-    virtual void run(void* param);
-    
-    /// Empty stop
-    virtual void stop() {};
-  };
-  
- } // end of namespace server
-
-} // end of namespace castor
-
-
-
diff --git a/tapeserver/castor/server/MultiThreadedDaemon.hpp b/tapeserver/castor/server/MultiThreadedDaemon.hpp
deleted file mode 100644
index d6c90ae15b..0000000000
--- a/tapeserver/castor/server/MultiThreadedDaemon.hpp
+++ /dev/null
@@ -1,169 +0,0 @@
-/*******************************************************************************
- *
- * This file is part of the Castor project.
- * See http://castor.web.cern.ch/castor
- *
- * Copyright (C) 2003  CERN
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * @author Castor Dev team, castor-dev@cern.ch
- ******************************************************************************/
-
-#pragma once
-
-#include "castor/server/BaseThreadPool.hpp"
-#include "castor/server/Daemon.hpp"
-#include "castor/server/AllInOneLockingUtility.hpp"
-
-#include <sstream>
-
-namespace castor {
-namespace server {
-
-/**
- * This class represents a multi-threaded daemon.
- */
-class MultiThreadedDaemon: public Daemon {
-
-public:
-
-  /**
-   * Constants for handling signals - see the signal handler thread.
-   */
-  static const int RESTART_GRACEFULLY = 1;
-  static const int STOP_GRACEFULLY = 2;
-  static const int STOP_NOW = 3;
-  static const int CHILD_STOPPED = 4;
-
-  /**
-   * Constructor
-   *
-   * @param stdOut Stream representing standard out.
-   * @param stdErr Stream representing standard error.
-   * @param log Object representing the API of the CASTOR logging system.
-   */
-  MultiThreadedDaemon(std::ostream &stdOut, std::ostream &stdErr,
-    log::Logger &log) throw();
-
-  /**
-   * Destructor.
-   */
-  virtual ~MultiThreadedDaemon() throw();
-
-  /**
-   * Gets a pool by its name initial.
-   * @param nameIn the name initial
-   * @throw castor::exception::Exception in case it was not found
-   */
-  BaseThreadPool* getThreadPool(const char nameIn);
-
-  /**
-   * Calls resetMetrics on all registered thread pools
-   */
-  void resetAllMetrics() throw();
-
-  /**
-   * Adds a thread pool to this server
-   *
-   * @param tpool The thread pool to be added.
-   */
-  void addThreadPool(BaseThreadPool *const pool) throw();
-
-  /**
-   * Starts all the thread pools
-   *
-   * @param runAsStagerSuperuser Set to true if the user ID and group ID of the
-   * daemon should be set to those of the stager superuser.
-   */
-  void start(const bool runAsStagerSuperuser);
-
-  /**
-   * Adds a dedicated UDP thread pool for getting wakeup notifications
-   * from other Castor daemons. Those notifications are supposed to be
-   * sent using the Daemon::sendNotification() method.
-   * @param port the UDP port where to listen
-   */
-  void addNotifierThreadPool(const int port);
-
-  /**
-   * Parses a command line to set the server options.
-   *
-   * @param argc The size of the command-line vector.
-   * @param argv The command-line vector.
-   */
-  virtual void parseCommandLine(int argc, char *argv[]);
-
-protected:
-
-  /**
-   * Shuts down the daemon gracefully.
-   */
-  void shutdownGracefully() throw();
-
-  /**
-   * Sends a shutdown message to all thread pools, then
-   * waits for all threads to terminate before returning.
-   * This implements a graceful kill and is triggered by SIGTERM.
-   */
-  virtual void waitAllThreads() throw();
-
-  /**
-   * Prints out the online help
-   */
-  virtual void help(const std::string &programName) throw();
-
-private:
-
-  /**
-   * Sets up the signal handling for this multi-threaded daemon.
-   */
-  void setupMultiThreadedSignalHandling() ;
-
-  /**
-   * Handles signals and performs graceful/immediate stop.
-   * Called by start()
-   */
-  void handleSignals();
-
-  /**
-   * Command line parameters. Includes by default a parameter
-   * per each thread pool to specify the number of threads.
-   */
-  std::ostringstream m_cmdLineParams;
-
-  /**
-   * List of thread pools running on this server,
-   * identified by their name initials (= cmd line parameter).
-   */
-  std::map<const char, BaseThreadPool*> m_threadPools;
-
-  /**
-   * Set of caught signals.
-   */
-  sigset_t m_signalSet;
-
-  /**
-   * A mutex for the signal handler thread.
-   */
-  AllInOneLockingUtility* m_signalMutex;
-
-  /**
-   * Entry point for the signal handler thread.
-   */
-  static void* s_signalHandler(void* arg);
-
-}; // class MultiThreadedDaemon
-
-} // namespace server
-} // namespace castor
-
diff --git a/tapeserver/castor/server/TCPListenerThreadPool.hpp b/tapeserver/castor/server/TCPListenerThreadPool.hpp
deleted file mode 100644
index 90c1313fcc..0000000000
--- a/tapeserver/castor/server/TCPListenerThreadPool.hpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/******************************************************************************
- *
- * This file is part of the Castor project.
- * See http://castor.web.cern.ch/castor
- *
- * Copyright (C) 2003  CERN
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *
- * Listener thread pool based on TCP
- *
- * @author Castor Dev team, castor-dev@cern.ch
- *****************************************************************************/
-
-#pragma once
-
-#include <iostream>
-#include <string>
-#include "castor/server/ListenerThreadPool.hpp"
-#include "castor/exception/Exception.hpp"
-
-namespace castor {
-
-  // Forward declaration
-  namespace io {
-    class ServerSocket;
-  }
-
-  namespace server {
-
-    /**
-     * TCP Listener thread pool: handles a (TCP) ServerSocket and allows
-     * processing upcoming requests in dedicated threads.
-     */
-    class TCPListenerThreadPool : public ListenerThreadPool {
-
-    public:
-
-      /**
-       * Constructor for a TCP listener with a fixed number of threads.
-       * @param poolName, thread as in BaseThreadPool
-       * @param listenPort the port to be used by the listening socket.
-       * @param waitIfBusy true to wait on dispatching to a worker thread
-       * even if all threads are busy, as opposed to reject the connection.
-       * True by default for this TCP-based listener (note there's no
-       * default for the generic ListenerThreadPool).
-       * @param nbThreads as in DynamicThreadPool
-       */
-      TCPListenerThreadPool(const std::string poolName, castor::server::IThread* thread,
-                            unsigned int listenPort,
-                            bool waitIfBusy = true,
-                            unsigned int nbThreads = DEFAULT_THREAD_NUMBER)
-        ;
-  
-      /**
-       * Constructor for a TCP listener with a dynamic number of threads.
-       * @param poolName, thread as in BaseThreadPool
-       * @param listenPort the port to be used by the listening socket.
-       * @param waitIfBusy true to wait on dispatching to a worker thread
-       * even if all threads are busy, as opposed to reject the connection.
-       * @param initThreads, maxThreads, threshold, maxTasks as in DynamicThreadPool
-       */
-      TCPListenerThreadPool(const std::string poolName, castor::server::IThread* thread,
-                            unsigned int listenPort,
-                            bool waitIfBusy,
-                            unsigned int initThreads, unsigned int maxThreads,
-                            unsigned int threshold = DEFAULT_THRESHOLD,
-                            unsigned int maxTasks  = DEFAULT_MAXTASKS)      
-        ;
-                       
-      /**
-       * Destructor
-       */
-      virtual ~TCPListenerThreadPool() throw();
-  
-    protected:
-
-      /**
-       * Binds a standard ServerSocket to the given port.
-       * @throw castor::exception::Exception if the port is busy.
-       */
-      virtual void bind() ;
-
-      /**
-       * The listening loop implementation for this Listener, based on standard ServerSocket.
-       * Child classes must override this method to provide different listener behaviors;
-       * it is expected that this method implements a never-ending loop.
-       */
-      virtual void listenLoop();
-
-      /**
-       * Terminates the work to be done when the thread pool is exhausted,
-       * by simply closing the connection to the client.
-       * @param param user parameter that would have been passed to a thread
-       */
-      virtual void terminate(void* param) throw();
-      
-    };
-
-  } // end of namespace server
-
-} // end of namespace castor
-
-
diff --git a/tapeserver/castor/server/UDPListenerThreadPool.hpp b/tapeserver/castor/server/UDPListenerThreadPool.hpp
deleted file mode 100644
index a6733cdba3..0000000000
--- a/tapeserver/castor/server/UDPListenerThreadPool.hpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/******************************************************************************
- *
- * This file is part of the Castor project.
- * See http://castor.web.cern.ch/castor
- *
- * Copyright (C) 2003  CERN
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *
- * Listener thread pool based on UDP
- *
- * @author Castor Dev team, castor-dev@cern.ch
- *****************************************************************************/
-
-#pragma once
-
-#include <iostream>
-#include <string>
-#include "castor/server/ListenerThreadPool.hpp"
-#include "castor/exception/Exception.hpp"
-
-namespace castor {
-
-  // Forward declaration
-  namespace io {
-    class UDPSocket;
-  }
-
-  namespace server {
-
-    /**
-     * UDP Listener thread pool: handles a UDPSocket and allows
-     * processing upcoming requests in dedicated threads.
-     */
-    class UDPListenerThreadPool : public ListenerThreadPool {
-
-    public:
-
-      /**
-       * Constructor
-       * @param poolName, thread as in BaseThreadPool
-       * @param listenPort the TCP port to which to attach the ServerSocket.
-       * @param waitIfBusy true to wait on dispatching to a worker thread
-       * even if all threads are busy, as opposed to reject the connection.
-       * False by default for this UDP-based listener (note there's no
-       * default for the generic ListenerThreadPool).
-       * @param nbThreads as in ListenerThreadPool. This listener is not dynamic.
-       */
-      UDPListenerThreadPool(const std::string poolName, castor::server::IThread* thread,
-                            const int listenPort, bool waitIfBusy = false,
-                            unsigned nbThreads = castor::server::DEFAULT_THREAD_NUMBER) throw();
-
-    protected:
-
-      /**
-       * Binds a standard UDPSocket to the given port.
-       * @throw castor::exception::Exception if the port is busy.
-       */
-      virtual void bind() ;
-
-      /**
-       * The listening loop implementation for this Listener, based on standard UDPSocket.
-       * Child classes must override this method to provide different listener behaviors;
-       * it is expected that this method implements a never-ending loop.
-       */
-      virtual void listenLoop();
-
-      /**
-       * Terminates the work to be done when the thread pool is exhausted,
-       * by simply freeing the received object.
-       * @param param user parameter that would have been passed to a thread
-       */
-      virtual void terminate(void* param) throw();
-
-    };
-
-  } // end of namespace server
-
-} // end of namespace castor
-
-
diff --git a/tapeserver/castor/server/metrics/Histogram.cpp b/tapeserver/castor/server/metrics/Histogram.cpp
deleted file mode 100644
index b13041d68f..0000000000
--- a/tapeserver/castor/server/metrics/Histogram.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/******************************************************************************
- *
- * This file is part of the Castor project.
- * See http://castor.web.cern.ch/castor
- *
- * Copyright (C) 2003  CERN
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * @(#)BaseClient.cpp,v 1.37 $Release$ 2006/02/16 15:56:58 sponcec3
- *
- *
- *
- * @author Castor Dev team, castor-dev@cern.ch
- *****************************************************************************/
-
-#include "castor/server/metrics/Histogram.hpp"
-
-#include <errno.h>
-
-//------------------------------------------------------------------------------
-// Constructor
-//------------------------------------------------------------------------------
-castor::server::metrics::Histogram::Histogram(std::string name,
-  CounterInstantiator instantiator) : m_name(name),
-  m_instantiator(instantiator), m_mutex(0)
-{}
-
-//------------------------------------------------------------------------------
-// Destructor
-//------------------------------------------------------------------------------
-castor::server::metrics::Histogram::~Histogram()
-{
-  for(CountersIter c = cBegin(); c != cEnd(); c++) {
-    delete c->second;
-  }
-}
-
-//------------------------------------------------------------------------------
-// notifyNewValue
-//------------------------------------------------------------------------------
-void castor::server::metrics::Histogram::notifyNewValue(castor::IObject* obj)
-  
-{
-  if(m_instantiator != 0) {
-    try {
-      // Take a lock so that the same counter can't be added twice
-      m_mutex.lock();
-      CountersIter ci;
-      for(ci = cBegin(); ci != cEnd(); ci++) {
-        if(int i = ci->second->match(obj)) {
-          // another counter already exists with this name, merge the two;
-          // note that this may happen due to a race condition between multiple
-          // threads all trying to add the same counter
-          ci->second->inc(i);
-          break;
-        }
-      }
-      if(ci == cEnd()) {
-        // the counter does not exist indeed, instantiate it and add to the map
-        addCounter((*m_instantiator)(obj));
-      }
-      m_mutex.release();
-    }
-    catch (castor::exception::Exception& e) {
-      // An exception here is most likely a problem with mutexes. Try to release
-      // our mutex before rethrowing
-      try {
-        m_mutex.release();
-      } catch (castor::exception::Exception& ignored) {}
-      throw e;
-    }
-  }
-}
-
-//------------------------------------------------------------------------------
-// printXml
-//------------------------------------------------------------------------------
-std::string castor::server::metrics::Histogram::printXml(
-  std::string counterName)
-{
-  std::ostringstream ss;
-  ss << "<histogram name='" << m_name << "'>\n";
-  if(counterName == "*") {
-    for(CountersIter c = cBegin(); c != cEnd(); c++) {
-      ss << "  " << c->second->printXml();
-    }
-  }
-  else if(m_counters.find(counterName) != m_counters.end()) {
-    ss << "  " << m_counters[counterName]->printXml();
-  }
-  else {
-    castor::exception::Exception e(ENOENT);
-    e.getMessage() << "The requested counter was not found";
-    throw e;
-  }
-  ss << "</histogram>\n";
-  return ss.str();
-}
diff --git a/tapeserver/castor/server/metrics/Histogram.hpp b/tapeserver/castor/server/metrics/Histogram.hpp
deleted file mode 100644
index 6cfc900813..0000000000
--- a/tapeserver/castor/server/metrics/Histogram.hpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/******************************************************************************
- *
- * This file is part of the Castor project.
- * See http://castor.web.cern.ch/castor
- *
- * Copyright (C) 2003  CERN
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *
- *
- *
- * @author Castor Dev team, castor-dev@cern.ch
- *****************************************************************************/
-
-#pragma once
-
-// Include Files
-#include "castor/IObject.hpp"
-#include "castor/server/metrics/Counter.hpp"
-#include "castor/server/AllInOneLockingUtility.hpp"
-
-#include <string>
-#include <map>
-
-namespace castor  {
-namespace server  {
-namespace metrics {
-
-typedef std::map<std::string, Counter*>::iterator CountersIter; 
-
-/**
- * A class representing a collection of counters, which break down
- * a given "dimension" or metric into different values.
- */
-class Histogram {
-  
-public:
-  /**
-   * Default constructor
-   * @param name Name of this histogram
-   * @param instantiator A function pointer to add counters
-   * to this histogram when no match was found. The type is defined as:
-   * typedef Counter* (*CounterInstantiator)(castor::IObject* obj);
-   */
-  Histogram(std::string name, CounterInstantiator instantiator);
-  
-  /// Default destructor
-  virtual ~Histogram();
-  
-  /**
-   * This method is called whenever no counters
-   * matched the passed value for this histogram.
-   * The default implementation checks that there's indeed no
-   * matching counter in a thread-safe way and eventually
-   * adds a new counter for this value by calling
-   * the internal instantiator.
-   * @param obj The value that should be counted 
-   * @throw exception in case of mutex errors
-   */
-  virtual void notifyNewValue(castor::IObject* obj);
-      
-  /**
-   * Returns an XML representation of this histogram
-   * @param counterName The counter to be included, '*' for all
-   * @throw castor::exception::Exception(ENOENT) when counter not found
-   */      
-  std::string printXml(std::string counterName)
-        ;
-      
-  /// Gets this histogram's name
-  std::string getName() {
-    return m_name;
-  }
-  
-  /// Inline method to access the counters through an iterator
-  CountersIter cBegin() {
-    return m_counters.begin();
-  }
-  
-  /// Inline method to access the counters through an iterator
-  CountersIter cEnd() {
-    return m_counters.end();
-  }
-
-  /// Returns a counter given its name
-  Counter* getCounter(std::string name) {
-    if(m_counters.find(name) != m_counters.end()) {
-      return m_counters[name];
-    }
-    return 0;
-  }
-      
-  /**
-   * Add a new counter to this histogram. This method
-   * is not protected by the mutex and it is deprecated
-   * to use it from any user application code: users should
-   * rely on the notifyNewValue method.
-   * @param c The Counter to be added to this histogram
-   */
-  void addCounter(Counter* c) {
-    if(c) {
-      m_counters[c->getName()] = c;
-    }
-  }        
-
-protected:
-
-  /// Name of this histogram
-  std::string m_name;
-  
-  /// Hash map of all counters for this histogram, indexed by name
-  std::map<std::string, Counter*> m_counters;
-  
-  /// Instantiator method to add new counters on no match events
-  CounterInstantiator m_instantiator;
-  
-  /// Mutex to protect the addition of new counters     
-  castor::server::AllInOneLockingUtility m_mutex;
-
-}; // Class Histogram
-
-} // namespace metrics
-} // namespace server
-} // namespace castor
diff --git a/tapeserver/castor/server/metrics/MetricsCollector.cpp b/tapeserver/castor/server/metrics/MetricsCollector.cpp
deleted file mode 100644
index f203ad548b..0000000000
--- a/tapeserver/castor/server/metrics/MetricsCollector.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-/******************************************************************************
- *
- * This file is part of the Castor project.
- * See http://castor.web.cern.ch/castor
- *
- * Copyright (C) 2003  CERN
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * @(#)BaseClient.cpp,v 1.37 $Release$ 2006/02/16 15:56:58 sponcec3
- *
- *
- *
- * @author Castor Dev team, castor-dev@cern.ch
- *****************************************************************************/
-
-#include "castor/server/metrics/InternalCounter.hpp"
-#include "castor/server/metrics/MetricsCollector.hpp"
-#include "castor/server/metrics/UpdateThread.hpp"
-#include "getconfent.h"
-
-#include <fstream>
-#include <time.h>
-#include <typeinfo>
-
-// Initialization of the singleton
-castor::server::metrics::MetricsCollector*
-  castor::server::metrics::MetricsCollector::s_instance(0);
-
-//------------------------------------------------------------------------------
-// getInstance
-//------------------------------------------------------------------------------
-castor::server::metrics::MetricsCollector*
-  castor::server::metrics::MetricsCollector::getInstance(
-   castor::server::MultiThreadedDaemon* daemon)
-{
-  if(s_instance == 0 && daemon) {
-    // No need to protect this with mutexes as the instantiation
-    // is always performed at startup before creating all threads
-    s_instance = new MetricsCollector(*daemon);
-    daemon->addThreadPool(s_instance);
-  }
-  return s_instance;
-}
-
-
-//------------------------------------------------------------------------------
-// Constructor
-//------------------------------------------------------------------------------
-castor::server::metrics::MetricsCollector::MetricsCollector(
-  castor::server::MultiThreadedDaemon& daemon) :
-  castor::server::SignalThreadPool("metrics", new UpdateThread()),
-  m_daemon(daemon)
-{
-  m_nbThreads = 1;
-  std::stringstream ss;
-  char* buf = getconfent("Metrics", "FileLocation", 0);
-  if(buf == 0) {
-    ss << "/var/spool/castor/";
-  }
-  else {
-    ss << buf << "/";
-  }
-  ss << m_daemon.getServerName();
-  buf = getenv("CASTOR_ROLE");
-  if(buf != 0) {
-    m_role = buf;
-    ss << "." << buf;
-  }
-  else
-    m_role = "";
-  ss << ".xml";
-  m_dumpFileLocation = ss.str().c_str();
-  m_startupTime = time(NULL);
-  
-  // add empty histograms for internal metrics. Note they don't have a counter instantiator,
-  // as the thread pools register themselves to the histograms at init time
-  addHistogram(new Histogram("AvgTaskTime", 0));
-  addHistogram(new Histogram("AvgQueuingTime", 0));
-  addHistogram(new Histogram("ActivityFactor", 0));
-  addHistogram(new Histogram("LoadFactor", 0));
-  addHistogram(new Histogram("BacklogFactor", 0));
-}
-
-//------------------------------------------------------------------------------
-// Destructor
-//------------------------------------------------------------------------------
-castor::server::metrics::MetricsCollector::~MetricsCollector() throw()
-{
-  for(HistogramsIter h = histBegin(); h != histEnd(); h++)
-    delete h->second;
-}
-
-//------------------------------------------------------------------------------
-// updateHistograms
-//------------------------------------------------------------------------------
-void castor::server::metrics::MetricsCollector::updateHistograms(
-  castor::IObject* obj)
-{
-  for(HistogramsIter h = histBegin(); h != histEnd(); h++) {
-    CountersIter c;
-    for(c = h->second->cBegin(); c != h->second->cEnd(); c++) {
-      if(int i = c->second->match(obj)) {
-        c->second->inc(i);
-        // we can't have other matching counters, stop here
-        break;
-      }
-    }
-    
-    // if no match, notify the histogram of this new value. This eventually
-    // triggers the creation of a new counter, which is protected by
-    // a mutex at the histogram level. 
-    if(c == h->second->cEnd()) {
-      h->second->notifyNewValue(obj);
-    }
-  }
-}
-
-//------------------------------------------------------------------------------
-// printXml
-//------------------------------------------------------------------------------
-std::string castor::server::metrics::MetricsCollector::printXml(
-  std::string histName, std::string counterName)
-{
-  std::ostringstream ss;
-  time_t t = time(NULL);
-  char currTime[20];
-
-  // get timing information
-  time_t upTime = t - m_startupTime;
-  strftime(currTime, 20, "%Y-%m-%dT%H:%M:%S", localtime(&t));
-  int s, m, h;
-  s = upTime % 60;
-  upTime /= 60;
-  m = upTime % 60;
-  upTime /= 60;
-  h = upTime % 24;
-  upTime /= 24;   // upTime == days
-  
-  // print some header info
-  ss << "<metrics>\n"
-     << "<daemon name='" << m_daemon.getServerName();
-  if(m_role != "") {
-    ss << "' role='" << m_role;
-  }
-  ss << "' PID='" << getpid() << "'/>\n"
-     << "<time upTime='";
-  ss << (upTime < 10 ? "0" : "") << upTime
-     << (h < 10 ? "d 0" : "d ") << h
-     << (m < 10 ? ":0" : ":") << m
-     << (s < 10 ? ":0" : ":") << s
-     << "' currTime='" << currTime
-     << "' timestamp='" << t << "'/>\n";
-     
-  // print data for the required histograms/counters
-  if(histName == "*") {
-    for(HistogramsIter h = histBegin(); h != histEnd(); h++) {
-      ss << h->second->printXml("*");
-    }
-  }
-  else {
-    if(m_histograms.find(histName) != m_histograms.end()) {
-     ss << m_histograms[histName]->printXml(counterName);
-    } else {
-      castor::exception::Exception e(ENOENT);
-      e.getMessage() << "The requested histogram was not found";
-      throw e;
-    }
-  }
-  ss << "</metrics>\n";
-  
-  return ss.str();
-}
-
-//------------------------------------------------------------------------------
-// dumpToFile
-//------------------------------------------------------------------------------
-void castor::server::metrics::MetricsCollector::dumpToFile()
-{
-  std::ofstream f(m_dumpFileLocation.c_str());
-  if(f.is_open()) {
-    f << printXml("*", "*") << std::endl; 
-    f.close();
-  }
-}
diff --git a/tapeserver/castor/server/metrics/MetricsCollector.hpp b/tapeserver/castor/server/metrics/MetricsCollector.hpp
deleted file mode 100644
index d4c510a4a7..0000000000
--- a/tapeserver/castor/server/metrics/MetricsCollector.hpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/******************************************************************************
- *
- * This file is part of the Castor project.
- * See http://castor.web.cern.ch/castor
- *
- * Copyright (C) 2003  CERN
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *
- *
- *
- * @author Castor Dev team, castor-dev@cern.ch
- *****************************************************************************/
-
-#pragma once
-
-#include "castor/IObject.hpp"
-#include "castor/exception/Exception.hpp"
-#include "castor/server/metrics/Histogram.hpp"
-#include "castor/server/MultiThreadedDaemon.hpp"
-#include "castor/server/SignalThreadPool.hpp"
-
-#include <map>
-#include <string>
-
-namespace castor {
-namespace server {
-namespace metrics {
-
-typedef std::map<std::string, Histogram*>::iterator HistogramsIter; 
-    
-/**
- * A singleton class holding all collected metrics for all "dimensions"
- * or histograms defined by the user application.
- */
-class MetricsCollector : public SignalThreadPool {
-
-public:    
-  /// This class is a singleton
-  static MetricsCollector* getInstance(
-    castor::server::MultiThreadedDaemon* daemon = 0);
-
-  /// Default destructor
-  virtual ~MetricsCollector() throw();
-
-  /// Method to be called by application's threads
-  /// to count the object represented by obj (e.g. a Request)
-  void updateHistograms(castor::IObject* obj)
-    ;
-
-  /// Add a new histogram to the system
-  void addHistogram(metrics::Histogram* h) {
-     m_histograms[h->getName()] = h;
-  }
-      
-  /**
-   * Prints an XML representation of the requested histogram/counter
-   * @param histName, countName the name of the histogram/counter
-   * @throw castor::exception::Exception(ENOENT) when data not found
-   */     
-  std::string printXml(std::string histName, std::string counterName)
-    ;
-    
-  /**
-   * Dumps the current metrics' values to a proc-like XML-formatted file.
-   * The file location is specified in castor.conf.
-   */
-  void dumpToFile();
-  
-  /**
-   * Calls resetAllMetrics on the daemon.
-   * @see BaseServer.resetAllMetrics
-   */
-  void resetAllMetrics() throw() {
-    m_daemon.resetAllMetrics();
-  }
-
-  /// Inline method to access the histograms through an iterator
-  HistogramsIter histBegin() {
-    return m_histograms.begin();
-  }
-  
-  /// Inline method to access the histograms through an iterator
-  HistogramsIter histEnd() {
-    return m_histograms.end();
-  }
-  
-  /// Returns an histogram given its name
-  metrics::Histogram* getHistogram(std::string name) {
-    if(m_histograms.find(name) != m_histograms.end()) {
-      return m_histograms[name];
-    }
-    return 0;
-  }
-
-private:
-  /// This singleton's instance
-  static MetricsCollector* s_instance;
-  
-  /// Default constructor
-  MetricsCollector(castor::server::MultiThreadedDaemon& daemon);
-  
-  /// Hash map of all histograms, indexed by name
-  std::map<std::string, Histogram*> m_histograms;
-  
-  /// Reference to the daemon for logging purposes and for resetAllMetrics
-  castor::server::MultiThreadedDaemon& m_daemon;
-  
-  /// Dump file location
-  std::string m_dumpFileLocation;
-  
-  /// Startup time of the daemon
-  time_t m_startupTime;
-  
-  /// Role of this daemon, for multi-role daemons (e.g. RH)
-  std::string m_role;
-
-}; // class MetricsCollector
-
-} // namespace metrics
-} // namespace server
-} // namespace castor
-
diff --git a/tapeserver/castor/tape/tapeserver/daemon/CatalogueDrive.hpp b/tapeserver/castor/tape/tapeserver/daemon/CatalogueDrive.hpp
index 324a49b7de..9dbafac6d6 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/CatalogueDrive.hpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/CatalogueDrive.hpp
@@ -209,7 +209,7 @@ public:
   /** 
    * Returns the catalogue cleaner-session associated with the tape drive.
    *
-   * This method throws a castor::exception::Exception if there is no
+   * This method throws a cta::exception::Exception if there is no
    * cleaner session associated with the tape drive.
    */
   const CatalogueCleanerSession &getCleanerSession() const;
@@ -217,7 +217,7 @@ public:
   /**
    * Returns the catalogue cleaner-session associated with the tape drive.
    *
-   * This method throws a castor::exception::Exception if there is no
+   * This method throws a cta::exception::Exception if there is no
    * cleaner session associated with the tape drive.
    */ 
   CatalogueCleanerSession &getCleanerSession();
@@ -225,7 +225,7 @@ public:
   /**
    * Returns the catalogue label-session associated with the tape drive.
    *
-   * This method throws a castor::exception::Exception if there is no
+   * This method throws a cta::exception::Exception if there is no
    * label session associated with the tape drive.
    */
   const CatalogueLabelSession &getLabelSession() const;
@@ -233,7 +233,7 @@ public:
   /**
    * Returns the catalogue label-session associated with the tape drive.
    *
-   * This method throws a castor::exception::Exception if there is no
+   * This method throws a cta::exception::Exception if there is no
    * label session associated with the tape drive.
    */
   CatalogueLabelSession &getLabelSession();
@@ -241,7 +241,7 @@ public:
   /**
    * Returns the catalogue transfer-session associated with the tape drive.
    *
-   * This method throws a castor::exception::Exception if there is no
+   * This method throws a cta::exception::Exception if there is no
    * transfer session associated with the tape drive.
    */
   const CatalogueTransferSession &getTransferSession() const;
@@ -249,7 +249,7 @@ public:
   /**
    * Returns the catalogue transfer-session associated with the tape drive.
    *
-   * This method throws a castor::exception::Exception if there is no
+   * This method throws a cta::exception::Exception if there is no
    * transfer session associated with the tape drive.
    */
   CatalogueTransferSession &getTransferSession();
@@ -257,7 +257,7 @@ public:
   /**
    * Gets the session asscoiated with the tape drive.
    *
-   * This method throws castor::exception::Exception if there is no session
+   * This method throws cta::exception::Exception if there is no session
    * currently associated with the tape drive.
    *
    * Please use either getCleanerSession(), getLabelSession() or
@@ -368,7 +368,7 @@ private:
    * Checks that there is a tape session currently associated with the
    * tape drive.
    *
-   * This method throws castor::exception::Exception if there is no
+   * This method throws cta::exception::Exception if there is no
    * tape session associated with the tape drive.
    */
   void checkForSession() const;
@@ -377,7 +377,7 @@ private:
    * Checks that there is a cleaner session currently associated with the
    * tape drive.
    *
-   * This method throws castor::exception::Exception if there is no
+   * This method throws cta::exception::Exception if there is no
    * cleaner session associated with the tape drive.
    */
   void checkForCleanerSession() const;
@@ -386,7 +386,7 @@ private:
    * Checks that there is a label session currently associated with the
    * tape drive.
    *
-   * This method throws castor::exception::Exception if there is no
+   * This method throws cta::exception::Exception if there is no
    * label session associated with the tape drive.
    */
   void checkForLabelSession() const;
@@ -395,7 +395,7 @@ private:
    * Checks that there is a transfer session currently associated with the
    * tape drive.
    *
-   * This method throws castor::exception::Exception if there is no
+   * This method throws cta::exception::Exception if there is no
    * transfer session associated with the tape drive.
    */
   void checkForTransferSession() const;
diff --git a/tapeserver/castor/tape/tapeserver/daemon/CatalogueLabelSession.hpp b/tapeserver/castor/tape/tapeserver/daemon/CatalogueLabelSession.hpp
index 432c719837..314c7fd123 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/CatalogueLabelSession.hpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/CatalogueLabelSession.hpp
@@ -201,7 +201,7 @@ private:
    * Determines whether or not the user of the label session has the access
    * rights to label the tape.
    *
-   * This method throws a castor::exception::Exception if the user does not
+   * This method throws a cta::exception::Exception if the user does not
    * have the necessary access rights or there is an error which prevents this
    * method for determining if they have such rights.
    *
diff --git a/tapeserver/castor/tape/tapeserver/daemon/CatalogueTransferSession.hpp b/tapeserver/castor/tape/tapeserver/daemon/CatalogueTransferSession.hpp
index 8c19bce118..9253485ef4 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/CatalogueTransferSession.hpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/CatalogueTransferSession.hpp
@@ -133,7 +133,7 @@ public:
    * Gets the access mode, either recall (WRITE_DISABLE) or migration
    * (WRITE_ENABLE).
    *
-   * This method throws a castor::exception::Exception if the access mode is
+   * This method throws a cta::exception::Exception if the access mode is
    * not yet nknown.
    *
    * @return The access mode.
diff --git a/tapeserver/castor/tape/tapeserver/daemon/DiskReadTaskTest.cpp b/tapeserver/castor/tape/tapeserver/daemon/DiskReadTaskTest.cpp
index ccb456fc55..6665669602 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/DiskReadTaskTest.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/DiskReadTaskTest.cpp
@@ -50,7 +50,7 @@ namespace unitTests{
   
   struct MockMigrationReportPacker : public MigrationReportPacker {
     void reportCompletedJob(std::unique_ptr<cta::ArchiveJob> successfulArchiveJob) {}
-    void reportFailedJob(std::unique_ptr<cta::ArchiveJob> failedArchiveJob, const castor::exception::Exception& ex) {}
+    void reportFailedJob(std::unique_ptr<cta::ArchiveJob> failedArchiveJob, const cta::exception::Exception& ex) {}
     void reportEndOfSession() {}
     void reportEndOfSessionWithErrors(const std::string msg, int error_code) {}
     void disableBulk() {}
diff --git a/tapeserver/castor/tape/tapeserver/file/CMakeLists.txt b/tapeserver/castor/tape/tapeserver/file/CMakeLists.txt
index c3c6cc3c2e..ae2af7686d 100644
--- a/tapeserver/castor/tape/tapeserver/file/CMakeLists.txt
+++ b/tapeserver/castor/tape/tapeserver/file/CMakeLists.txt
@@ -50,12 +50,15 @@ if(CMAKE_COMPILER_IS_GNUCC)
       PROPERTY COMPILE_FLAGS " -Wno-unused-local-typedefs")
     set_property(SOURCE FileTest.cpp
       PROPERTY COMPILE_FLAGS " -Wno-unused-local-typedefs")
+    set_property(SOURCE CryptoPPTest.cpp
+      PROPERTY COMPILE_FLAGS " -Wno-unused-local-typedefs")
   endif(GCC_VERSION_GE_4_8_0)
 endif(CMAKE_COMPILER_IS_GNUCC)
 
 add_library(ctatapeserverfileunittests SHARED
   StructuresTest.cpp
-  FileTest.cpp)
+  FileTest.cpp
+  CryptoPPTest.cpp)
 
 target_link_libraries(ctatapeserverfileunittests
   File)
diff --git a/tapeserver/castor/tape/tapeserver/file/CryptoPPTest.cpp b/tapeserver/castor/tape/tapeserver/file/CryptoPPTest.cpp
index 6ff81e27d6..83ba7b54d6 100644
--- a/tapeserver/castor/tape/tapeserver/file/CryptoPPTest.cpp
+++ b/tapeserver/castor/tape/tapeserver/file/CryptoPPTest.cpp
@@ -54,12 +54,12 @@ namespace unitTests {
       size_t pos1, pos2;
       pos1 = keyString.find(HEADER);
       if(pos1 == std::string::npos)
-          throw castor::exception::Exception(
+          throw cta::exception::Exception(
             "In DiskFileFactory::xrootCryptoPPPrivateKey, PEM header not found");
           
       pos2 = keyString.find(FOOTER, pos1+1);
       if(pos2 == std::string::npos)
-          throw castor::exception::Exception(
+          throw cta::exception::Exception(
             "In DiskFileFactory::xrootCryptoPPPrivateKey, PEM footer not found");
           
       // Start position and length
@@ -81,13 +81,13 @@ namespace unitTests {
       // BERDecodePrivateKey is a void function. Here's the only check
       // we have regarding the DER bytes consumed.
       if(!queue.IsEmpty())
-        throw castor::exception::Exception(
+        throw cta::exception::Exception(
           "In DiskFileFactory::xrootCryptoPPPrivateKey, garbage at end of key");
       
       CryptoPP::AutoSeededRandomPool prng;
       bool valid = m_key.Validate(prng, 3);
       if(!valid)
-        throw castor::exception::Exception(
+        throw cta::exception::Exception(
           "In DiskFileFactory::xrootCryptoPPPrivateKey, RSA private key is not valid");
     }
     operator CryptoPP::RSA::PrivateKey() {
@@ -163,7 +163,7 @@ namespace unitTests {
     }
   private:
     virtual void run() {
-      castor::tape::diskFile::DiskFileFactory dff("xroot", m_keyPath, 0);
+      castor::tape::diskFile::DiskFileFactory dff("xroot", m_keyPath);
       for (int i=0; i<5; i++) {
         // Read keys in parallel and in a loop to test MT protection of the
         // key reading, not protected here.
@@ -179,9 +179,9 @@ namespace unitTests {
       char path[100];
       strncpy(path, "/tmp/castorUnitTestPrivateKeyXXXXXX", 100);
       int tmpFileFd = mkstemp(path);
-      castor::exception::Errnum::throwOnMinusOne(tmpFileFd, "Error creating a temporary file");
+      cta::exception::Errnum::throwOnMinusOne(tmpFileFd, "Error creating a temporary file");
       m_path = path;
-      castor::exception::Errnum::throwOnMinusOne(write(tmpFileFd, content.c_str(), content.size()));
+      cta::exception::Errnum::throwOnMinusOne(write(tmpFileFd, content.c_str(), content.size()));
     }
     ~TempFileForXrootKey() {
       ::unlink(m_path.c_str());
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 6989b8f87d..1b0d4430c7 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -44,6 +44,7 @@ target_link_libraries(cta-unitTests
   ctaschedulerunittests
   ctaio
   ctadaemonunittests
+  ctamediachangerunittests
   ${GMOCK_LIB}
   gtest
   pthread)
-- 
GitLab