Commit 54ef4500 authored by Steven Murray's avatar Steven Murray
Browse files

Cleaned up (non-existant) command-line parameters

parent 62b0ab6b
......@@ -29,6 +29,7 @@
#include "castor/server/TCPListenerThreadPool.hpp"
#include "castor/tape/aggregator/AggregatorDlfMessageConstants.hpp"
#include "castor/tape/aggregator/AggregatorDaemon.hpp"
#include "castor/tape/aggregator/Constants.hpp"
#include "castor/tape/utils/utils.hpp"
#include "castor/tape/aggregator/VdqmRequestHandler.hpp"
#include "h/Cgetopt.h"
......@@ -67,20 +68,24 @@ int castor::tape::aggregator::AggregatorDaemon::main(const int argc,
// Parse the command line
try {
bool helpOption = false; // True if help option found on command-line
parseCommandLine(argc, argv, helpOption);
parseCommandLine(argc, argv);
// Pass the foreground option to the super class BaseDaemon
m_foreground = m_parsedCommandLine.foregroundOptionSet;
// Display usage message and exit if help option found on command-line
if(helpOption) {
if(m_parsedCommandLine.helpOptionSet) {
std::cout << std::endl;
castor::tape::aggregator::AggregatorDaemon::usage(std::cout);
castor::tape::aggregator::AggregatorDaemon::usage(std::cout,
AGGREGATORPROGRAMNAME);
std::cout << std::endl;
return 0;
}
} catch (castor::exception::Exception &ex) {
std::cerr << std::endl << "Failed to parse the command-line: "
<< ex.getMessage().str() << std::endl;
castor::tape::aggregator::AggregatorDaemon::usage(std::cerr);
castor::tape::aggregator::AggregatorDaemon::usage(std::cerr,
AGGREGATORPROGRAMNAME);
std::cerr << std::endl;
return 1;
}
......@@ -93,7 +98,7 @@ int castor::tape::aggregator::AggregatorDaemon::main(const int argc,
} catch (castor::exception::Exception &ex) {
std::cerr << std::endl << "Failed to start daemon: "
<< ex.getMessage().str() << std::endl << std::endl;
usage(std::cerr);
usage(std::cerr, AGGREGATORPROGRAMNAME);
std::cerr << std::endl;
return 1;
}
......@@ -105,9 +110,9 @@ int castor::tape::aggregator::AggregatorDaemon::main(const int argc,
//------------------------------------------------------------------------------
// usage
//------------------------------------------------------------------------------
void castor::tape::aggregator::AggregatorDaemon::usage(std::ostream &os)
throw() {
os << "\nUsage: aggregatord [options]\n"
void castor::tape::aggregator::AggregatorDaemon::usage(std::ostream &os,
const char *const programName) throw() {
os << "\nUsage: "<< programName << " [options]\n"
"\n"
"where options can be:\n"
"\n"
......@@ -153,14 +158,12 @@ void castor::tape::aggregator::AggregatorDaemon::logStart(const int argc,
// parseCommandLine
//------------------------------------------------------------------------------
void castor::tape::aggregator::AggregatorDaemon::parseCommandLine(
const int argc, char **argv, bool &helpOption)
throw(castor::exception::Exception) {
const int argc, char **argv) throw(castor::exception::Exception) {
static struct Coptions longopts[] = {
{"foreground", NO_ARGUMENT , NULL, 'f'},
{"config" , REQUIRED_ARGUMENT, NULL, 'c'},
{"help" , NO_ARGUMENT , NULL, 'h'},
{NULL , 0 , NULL, 0 }
{"foreground", NO_ARGUMENT, NULL, 'f'},
{"help" , NO_ARGUMENT, NULL, 'h'},
{NULL , 0 , NULL, 0 }
};
Coptind = 1;
......@@ -170,33 +173,10 @@ void castor::tape::aggregator::AggregatorDaemon::parseCommandLine(
while ((c = Cgetopt_long(argc, argv, "fc:p:h", longopts, NULL)) != -1) {
switch (c) {
case 'f':
m_foreground = true;
break;
case 'c':
{
FILE *fp = fopen(Coptarg, "r");
if(fp) {
// The file exists
fclose(fp);
} else {
// The file does not exist
std::stringstream oss;
oss << "Configuration file '" << Coptarg << "' does not exist";
// Log and throw an exception
castor::dlf::Param params[] = {
castor::dlf::Param("Function", __FUNCTION__),
castor::dlf::Param("Reason" , oss.str())};
castor::dlf::dlf_writep(nullCuuid, DLF_LVL_USER_ERROR,
AGGREGATOR_FAILED_TO_PARSE_COMMAND_LINE, params);
TAPE_THROW_EX(castor::exception::InvalidArgument,
": " << oss.str());
}
}
setenv("PATH_CONFIG", Coptarg, 1);
m_parsedCommandLine.foregroundOptionSet = true;
break;
case 'h':
helpOption = true;
m_parsedCommandLine.helpOptionSet = true;
break;
case '?':
{
......@@ -212,6 +192,7 @@ void castor::tape::aggregator::AggregatorDaemon::parseCommandLine(
TAPE_THROW_EX(castor::exception::InvalidArgument,
": " << oss.str());
}
break;
case ':':
{
std::stringstream oss;
......@@ -226,6 +207,7 @@ void castor::tape::aggregator::AggregatorDaemon::parseCommandLine(
TAPE_THROW_EX(castor::exception::InvalidArgument,
": " << oss.str());
}
break;
default:
{
std::stringstream oss;
......
......@@ -67,25 +67,41 @@ private:
*/
void logStart(const int argc, const char *const *const argv) throw();
/**
* Data type used to store the results of parsing the command-line.
*/
struct ParsedCommandLine {
bool foregroundOptionSet;
bool helpOptionSet;
ParsedCommandLine() :
foregroundOptionSet(false),
helpOptionSet(false) {
}
};
/**
* The results of parsing the command-line.
*/
ParsedCommandLine m_parsedCommandLine;
/**
* Parses the command-line arguments and sets the daemon options accordingly.
*
* @param argc Argument count from the executable's entry function: main().
* @param argv Argument vector from the executable's entry function: main().
* @param helpOption This method sets this parameter to true if the help
* option was found on the command-line, else this method sets it to false.
*/
void parseCommandLine(const int argc, char **argv, bool &helpRequested)
void parseCommandLine(const int argc, char **argv)
throw(castor::exception::Exception);
/**
* Writes the command-line usage message of the daemon onto the specified
* output stream.
* Writes the command-line usage message of the aggregator daemon onto the
* specified output stream.
*
* @param os Output stream to be written to.
* @param programName The program name of the aggregator daemon.
* @param programName The program name to be used in the message.
*/
void usage(std::ostream &os) throw();
void usage(std::ostream &os, const char *const programName) throw();
/**
* Creates the VDQM request handler thread pool.
......
/******************************************************************************
* Constants.hpp
* castor/tape/aggregator/Constants.hpp
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
......@@ -34,18 +34,19 @@ namespace castor {
namespace tape {
namespace aggregator {
const size_t HDRBUFSIZ = 3 * sizeof(uint32_t);
const size_t HOSTNAMEBUFLEN = 256;
const int LISTENBACKLOG = 2;
const int MAXINITMIGFILES = 2;
const uint32_t MIGRATEUMASK = 022;
const size_t MSGBUFSIZ = 1024;
const uint32_t RECALLUMASK = 077;
const char RECORDFORMAT[2] = "F";
const int RTCPDNETRWTIMEOUT = 5;
const int RTCPDCALLBACKTIMEOUT = 5;
const int RTCPDPINGTIMEOUT = 10;
const size_t SERVICENAMEBUFLEN = 256;
const size_t HDRBUFSIZ = 3 * sizeof(uint32_t);
const size_t HOSTNAMEBUFLEN = 256;
const int LISTENBACKLOG = 2;
const int MAXINITMIGFILES = 2;
const uint32_t MIGRATEUMASK = 022;
const size_t MSGBUFSIZ = 1024;
const char *const AGGREGATORPROGRAMNAME = "aggregatord";
const uint32_t RECALLUMASK = 077;
const char *const RECORDFORMAT = "F";
const int RTCPDNETRWTIMEOUT = 5;
const int RTCPDCALLBACKTIMEOUT = 5;
const int RTCPDPINGTIMEOUT = 10;
const size_t SERVICENAMEBUFLEN = 256;
} // namespace aggregator
} // namespace tape
......
/******************************************************************************
* Utils.cpp
*
* 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 Nicola.Bessone@cern.ch Steven.Murray@cern.ch
*****************************************************************************/
#include "castor/exception/Internal.hpp"
#include "castor/tape/aggregator/Constants.hpp"
#include "castor/tape/aggregator/Utils.hpp"
#include "h/rtcp_constants.h"
#include <arpa/inet.h>
#include <iostream>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
//-----------------------------------------------------------------------------
// toHex
//-----------------------------------------------------------------------------
void castor::tape::aggregator::utils::toHex(const uint64_t i, char *dst,
size_t dstLen) throw(castor::exception::Exception) {
// The largest 64-bit hexadecimal string "FFFFFFFFFFFFFFFF" would ocuppy 17
// characters (17 characters = 16 x 'F' + 1 x '\0')
const size_t minimumDstLen = 17;
// If the destination character string cannot store the largest 64-bit
// hexadecimal string
if(dstLen < minimumDstLen) {
castor::exception::Exception ex(EINVAL);
ex.getMessage() << __FUNCTION__
<< ": Destination character array is too small"
": Minimum = " << minimumDstLen
<< ": Actual = " << dstLen;
throw ex;
}
const char hexDigits[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F'};
char backwardsHexDigits[16];
utils::setBytes(backwardsHexDigits, '\0');
uint64_t exponent = 0;
uint64_t quotient = i;
int nbDigits = 0;
for(exponent=0; exponent<16; exponent++) {
backwardsHexDigits[exponent] = hexDigits[quotient % 16];
nbDigits++;
quotient = quotient / 16;
if(quotient== 0) {
break;
}
}
for(int d=0; d<nbDigits;d++) {
dst[d] = backwardsHexDigits[nbDigits-1-d];
}
dst[nbDigits] = '\0';
}
//-----------------------------------------------------------------------------
// copyString
//-----------------------------------------------------------------------------
void castor::tape::aggregator::utils::copyString(char *const dst,
const char *src, const size_t n) throw(castor::exception::Exception) {
const size_t srcLen = strlen(src);
if(srcLen >= n) {
castor::exception::Exception ex(EINVAL);
ex.getMessage() << __FUNCTION__
<< ": Source string is longer than destination. Source length: "
<< srcLen << " Max destination length: " << (n-1);
throw ex;
}
strncpy(dst, src, n);
*(dst+n-1) = '\0'; // Ensure destination is null terminated
}
//-----------------------------------------------------------------------------
// magicToStr
//-----------------------------------------------------------------------------
const char *castor::tape::aggregator::utils::magicToStr(const uint32_t magic)
throw() {
switch(magic) {
case RTCOPY_MAGIC_VERYOLD: return "RTCOPY_MAGIC_VERYOLD";
case RTCOPY_MAGIC_SHIFT : return "RTCOPY_MAGIC_SHIFT";
case RTCOPY_MAGIC_OLD0 : return "RTCOPY_MAGIC_OLD0";
case RTCOPY_MAGIC : return "RTCOPY_MAGIC";
case RFIO2TPREAD_MAGIC : return "RFIO2TPREAD_MAGIC";
default : return "UNKNOWN";
}
}
//-----------------------------------------------------------------------------
// rtcopyReqTypeToStr
//-----------------------------------------------------------------------------
const char *castor::tape::aggregator::utils::rtcopyReqTypeToStr(
const uint32_t reqType) throw() {
switch(reqType) {
case RTCP_TAPE_REQ : return "RTCP_TAPE_REQ";
case RTCP_FILE_REQ : return "RTCP_FILE_REQ";
case RTCP_NOMORE_REQ : return "RTCP_NOMORE_REQ";
case RTCP_TAPEERR_REQ : return "RTCP_TAPEERR_REQ";
case RTCP_FILEERR_REQ : return "RTCP_FILEERR_REQ";
case RTCP_ENDOF_REQ : return "RTCP_ENDOF_REQ";
case RTCP_ABORT_REQ : return "RTCP_ABORT_REQ";
case RTCP_DUMP_REQ : return "RTCP_DUMP_REQ";
case RTCP_DUMPTAPE_REQ : return "RTCP_DUMPTAPE_REQ";
case RTCP_KILLJID_REQ : return "RTCP_KILLJID_REQ";
case RTCP_RSLCT_REQ : return "RTCP_RSLCT_REQ";
case RTCP_PING_REQ : return "RTCP_PING_REQ";
case RTCP_HAS_MORE_WORK: return "RTCP_HAS_MORE_WORK";
default : return "UNKNOWN";
}
}
//-----------------------------------------------------------------------------
// procStatusToStr
//-----------------------------------------------------------------------------
const char *castor::tape::aggregator::utils::procStatusToStr(
const uint32_t procStatus) throw() {
switch(procStatus) {
case RTCP_WAITING : return "RTCP_WAITING";
case RTCP_POSITIONED : return "RTCP_POSITIONED";
case RTCP_PARTIALLY_FINISHED: return "RTCP_PARTIALLY_FINISHED";
case RTCP_FINISHED : return "RTCP_FINISHED";
case RTCP_EOV_HIT : return "RTCP_EOV_HIT";
case RTCP_UNREACHABLE : return "RTCP_UNREACHABLE";
case RTCP_REQUEST_MORE_WORK : return "RTCP_REQUEST_MORE_WORK";
default : return "UNKNOWN";
}
}
//------------------------------------------------------------------------------
// isValidUInt
//------------------------------------------------------------------------------
bool castor::tape::aggregator::utils::isValidUInt(const char *str)
throw() {
// An empty string is not a valid unsigned integer
if(*str == '\0') {
return false;
}
// For each character in the string
for(;*str != '\0'; str++) {
// If the current character is not a valid numerical digit
if(*str < '0' || *str > '9') {
return false;
}
}
return true;
}
//------------------------------------------------------------------------------
// drainFile
//------------------------------------------------------------------------------
ssize_t castor::tape::aggregator::utils::drainFile(const int fd)
throw(castor::exception::Exception) {
char buf[1024];
ssize_t rc = 0;
ssize_t total = 0;
do {
rc = read((int)fd, buf, sizeof(buf));
if(rc == -1) {
char codeStr[STRERRORBUFLEN];
strerror_r(errno, codeStr, sizeof(codeStr));
TAPE_THROW_EX(castor::exception::Internal,
": Failed to drain file"
": fd=" << fd <<
": Error=" << codeStr);
} else {
total += rc;
}
// while the end of file has not been reached
} while(rc != 0);
return total;
}
/******************************************************************************
* Utils.hpp
*
* 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 Nicola.Bessone@cern.ch Steven.Murray@cern.ch
*****************************************************************************/
#ifndef CASTOR_TAPE_AGGREGATOR_UTILS_HPP
#define CASTOR_TAPE_AGGREGATOR_UTILS_HPP 1
#include "castor/exception/Exception.hpp"
#include <errno.h>
#include <stdint.h>
#include <string>
#include <string.h>
#include <unistd.h>
/**
* The TAPE_THROW_EX macro throws an exception and automatically adds file,
* line and function strings to the message of the exception. Example usage:
*
* TAPE_THROW_EX(castor::exception::Internal,
* ": Failed to down cast reply object to tapegateway::FileToRecall");
*/
#define TAPE_THROW_EX(EXCEPTION, MSG) { \
EXCEPTION _ex_; \
\
_ex_.getMessage() \
<< "File=" << __FILE__ \
<< " Line=" << __LINE__ \
<< " Function=" << __FUNCTION__ \
<< MSG; \
throw _ex_; \
}
/**
* The TAPE_THROW_CODE macro throws an exception and automatically adds file,
* line and function strings to the message of the exception. Example usage:
*
* TAPE_THROW_CODE(EBADMSG,
* ": Unknown reply type "
* ": Reply type = " << reply->type());
*/
#define TAPE_THROW_CODE(CODE, MSG) { \
castor::exception::Exception _ex_(CODE); \
\
_ex_.getMessage() \
<< "File=" << __FILE__ \
<< " Line=" << __LINE__ \
<< " Function=" << __FUNCTION__ \
<< MSG ; \
throw _ex_; \
}
namespace castor {
namespace tape {
namespace aggregator {
namespace utils {
/**
* Writes the specified unsigned 64-bit integer into the specified
* destination character array as a hexadecimal string.
*
* This function allows user to allocate a character array on the stack and
* fill it with 64-bit hexadecimal string.
*
* @param i The unsigned 64-bit integer.
* @param dst The destination character array which should have a minimum
* length of 17 characters. The largest 64-bit hexadecimal string
* "FFFFFFFFFFFFFFFF" would ocuppy 17 characters (17 * characters =
* 16 x 'F' + 1 x '\0').
* @param dstLen The length of the destination character string.
*/
void toHex(const uint64_t i, char *dst, size_t dstLen)
throw(castor::exception::Exception);
/**
* Writes the specified unsigned 64-bit integer into the specified
* destination character array as a hexadecimal string.
*
* This function allows user to allocate a character array on the stack and
* fill it with 64-bit hexadecimal string.
*
* @param i The unsigned 64-bit integer.
* @param dst The destination character array.
*/
template<int n> void toHex(const uint64_t i, char (&dst)[n])
throw(castor::exception::Exception) {
toHex(i, dst, n);
}
/**
* Sets all the bytes of the specified object to the value of c.
*
* @param object The object whose bytes are to be set.
* @param c The value to set each byte of object.
*/
template<typename T> void setBytes(T &object, const int c) throw() {
memset(&object, c, sizeof(object));
}
/**
* Safely copies source string into destination string. The destination
* will always be null terminated if this function is successful.
*
* @param dst Destination string.
* @param src Source string.
* @param n The maximum number of characters to be copied from source to
* destination.
*/
void copyString(char *const dst, const char *src, const size_t n)
throw(castor::exception::Exception);
/**
* Safely copies source string into destination string. The destination
* will always be null terminated if this function is successful.
*
* @param dst Destination string.
* @param src Source string.
*/
template<int n> void copyString(char (&dst)[n], const char *src)
throw(castor::exception::Exception) {
copyString(dst, src, n);
}
/**
* Returns the string representation of the specified magic number.
*
* @param magic The magic number.
*/
const char *magicToStr(const uint32_t magic) throw();
/**
* Returns the string representation of the specified RTCOPY_MAGIC request
* type.
*
* @param reqType The RTCP request type.
*/
const char *rtcopyReqTypeToStr(const uint32_t reqType) throw();
/**
* Returns the string representation of the specified file request status
* code.
*
* @param reqType The file request status code.
*/
const char *procStatusToStr(const uint32_t procStatus) throw();
/**
* Checks if the specified string is a valid unsigned integer.
*
* @param str The string to be checked.
* @returns true if the string is a valid unsigned integer, else false.
*/