AggregatorDaemon.cpp 9.99 KB
Newer Older
1
/******************************************************************************
2
 *                 castor/tape/aggregator/AggregatorDaemon.cpp
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 *
 * 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 Steven Murray Steven.Murray@cern.ch
 *****************************************************************************/
 
 
#include "castor/exception/Internal.hpp"
27
#include "castor/exception/InvalidArgument.hpp"
28
#include "castor/tape/aggregator/AggregatorDlfMessageConstants.hpp"
29
#include "castor/tape/aggregator/AggregatorDaemon.hpp"
30
31
32
#include "h/tape_aggregator_constants.h"
#include "h/Cgetopt.h"
#include "h/common.h"
33
34
35
36
37


//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
38
castor::tape::aggregator::AggregatorDaemon::AggregatorDaemon()
39
  throw(castor::exception::Exception) :
40
  castor::server::BaseDaemon("aggregatord") {
41
  // Initializes the DLF logging including the definition of the predefined
42
43
44
  // messages.  Please not that castor::server::BaseServer::dlfInit can throw a
  // castor::exception::Exception.
  castor::server::BaseServer::dlfInit(s_dlfMessages);
45
46
47
}


48
49
50
51
52
53
54
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
castor::tape::aggregator::AggregatorDaemon::~AggregatorDaemon() throw() {
}


55
56
57
//------------------------------------------------------------------------------
// usage
//------------------------------------------------------------------------------
58
59
60
void castor::tape::aggregator::AggregatorDaemon::usage(std::ostream &os)
  throw() {
  os << "\nUsage: aggregatord [options]\n"
61
62
63
    "\n"
    "where options can be:\n"
    "\n"
64
65
66
    "\t-f, --foreground            Remain in the Foreground\n"
    "\t-c, --config config-file    Configuration file\n"
    "\t-h, --help                  Print this help and exit\n"
67
68
69
70
71
72
    "\n"
    "Comments to: Castor.Support@cern.ch" << std::endl;
}


//------------------------------------------------------------------------------
73
// logStart
74
//------------------------------------------------------------------------------
75
76
77
78
79
80
81
82
83
void castor::tape::aggregator::AggregatorDaemon::logStart(const int argc,
  const char *const *const argv) throw() {
  std::string concatenatedArgs;

  // Concatenate all of the command-line arguments into one string
  for(int i=0; i < argc; i++) {
    if(i != 0) {
      concatenatedArgs += " ";
    }
84

85
86
    concatenatedArgs += argv[i];
  }
87

88
89
90
91
92
  castor::dlf::Param params[] = {
    castor::dlf::Param("argv", concatenatedArgs)};
  castor::dlf::dlf_writep(nullCuuid, DLF_LVL_SYSTEM, AGGREGATOR_STARTED, 1,
    params);
}
93
94


95
96
97
98
99
100
//------------------------------------------------------------------------------
// parseCommandLine
//------------------------------------------------------------------------------
void castor::tape::aggregator::AggregatorDaemon::parseCommandLine(
  const int argc, char **argv, bool &helpOption)
  throw(castor::exception::Exception) {
101
102

  static struct Coptions longopts[] = {
103
104
105
106
    {"foreground", NO_ARGUMENT      , NULL, 'f'},
    {"config"    , REQUIRED_ARGUMENT, NULL, 'c'},
    {"help"      , NO_ARGUMENT      , NULL, 'h'},
    {NULL        , 0                , NULL,  0 }
107
108
109
110
111
112
  };

  Coptind = 1;
  Copterr = 0;

  char c;
113
  while ((c = Cgetopt_long(argc, argv, "fc:p:h", longopts, NULL)) != -1) {
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
    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";

129
          // Log and throw an exception
130
          castor::dlf::Param params[] = {
131
132
            castor::dlf::Param("Function", __PRETTY_FUNCTION__),
            castor::dlf::Param("Reason"  , oss.str())};
133
          castor::dlf::dlf_writep(nullCuuid, DLF_LVL_ERROR,
134
            AGGREGATOR_FAILED_TO_PARSE_COMMAND_LINE, 2, params);
135
136
137
          castor::exception::InvalidArgument ex;
          ex.getMessage() << oss.str();
          throw ex;
138
139
140
141
142
        }
      }
      setenv("PATH_CONFIG", Coptarg, 1);
      break;
    case 'h':
143
144
      helpOption = true;
      break;
145
146
147
148
149
    case '?':
      {
        std::stringstream oss;
        oss << "Unknown command-line option: " << (char)Coptopt;

150
        // Log and throw an exception
151
        castor::dlf::Param params[] = {
152
153
          castor::dlf::Param("Function", __PRETTY_FUNCTION__),
          castor::dlf::Param("Reason"  , oss.str())};
154
        castor::dlf::dlf_writep(nullCuuid, DLF_LVL_ERROR,
155
          AGGREGATOR_FAILED_TO_PARSE_COMMAND_LINE, 2, params);
156
157
158
        castor::exception::InvalidArgument ex;
        ex.getMessage() << oss.str();
        throw ex;
159
160
161
162
163
164
      }
    case ':':
      {
        std::stringstream oss;
        oss << "An option is missing a parameter";

165
        // Log and throw an exception
166
        castor::dlf::Param params[] = {
167
168
          castor::dlf::Param("Function", __PRETTY_FUNCTION__),
          castor::dlf::Param("Reason"  , oss.str())};
169
        castor::dlf::dlf_writep(nullCuuid, DLF_LVL_ERROR,
170
          AGGREGATOR_FAILED_TO_PARSE_COMMAND_LINE, 2, params);
171
172
173
        castor::exception::InvalidArgument ex;
        ex.getMessage() << oss.str();
        throw ex;
174
175
176
177
178
179
180
      }
    default:
      {
        std::stringstream oss;
        oss << "Cgetopt_long returned the following unknown value: 0x"
          << std::hex << (int)c;

181
        // Log and throw an exception
182
        castor::dlf::Param params[] = {
183
184
          castor::dlf::Param("Function", __PRETTY_FUNCTION__),
          castor::dlf::Param("Reason"  , oss.str())};
185
        castor::dlf::dlf_writep(nullCuuid, DLF_LVL_ERROR,
186
          AGGREGATOR_FAILED_TO_PARSE_COMMAND_LINE, 2, params);
187
188
189
        castor::exception::Internal ex;
        ex.getMessage() << oss.str();
        throw ex;
190
191
192
193
      }
    }
  }

194
  if(Coptind > argc) {
195
    std::stringstream oss;
196
      oss << "Internal error.  Invalid value for Coptind: " << Coptind;
197
198
199

    // Log and throw an exception
    castor::dlf::Param params[] = {
200
201
      castor::dlf::Param("Function", __PRETTY_FUNCTION__),
      castor::dlf::Param("Reason", oss.str())};
202
    castor::dlf::dlf_writep(nullCuuid, DLF_LVL_ERROR,
203
      AGGREGATOR_FAILED_TO_PARSE_COMMAND_LINE, 2, params);
204
205
206
    castor::exception::Internal ex;
    ex.getMessage() << oss.str();
    throw ex;
207
208
  }

209
  // If there is some extra text on the command-line which has not been parsed
210
  if(Coptind < argc)
211
  {
212
    std::stringstream oss;
213
      oss << "Unexpected command-line argument: " << argv[Coptind]
214
      << std::endl;
215
216
217

    // Log and throw an exception
    castor::dlf::Param params[] = {
218
219
      castor::dlf::Param("Function", __PRETTY_FUNCTION__),
      castor::dlf::Param("Reason"  , oss.str())};
220
    castor::dlf::dlf_writep(nullCuuid, DLF_LVL_ERROR,
221
      AGGREGATOR_FAILED_TO_PARSE_COMMAND_LINE, 2, params);
222
223
224
225
226
227
228
    castor::exception::InvalidArgument e;
    e.getMessage() << oss.str();
    throw e;
  }
}


229
//------------------------------------------------------------------------------
230
// getVdqmListenPort()
231
//------------------------------------------------------------------------------
232
int castor::tape::aggregator::AggregatorDaemon::getVdqmListenPort()
233
  throw(castor::exception::InvalidConfigEntry) {
234
235
  int port = AGGREGATOR_VDQMPORT; // Initialise to default value
  const char *const configEntry = getconfent("TAPEAGGREGATOR", "VDQMPORT", 0);
236
237
238
239
240

  if(configEntry != NULL) {
    if(isAValidUInt(configEntry)) {
      port = atoi(configEntry);
    } else {
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
      castor::exception::InvalidConfigEntry ex("TAPEAGGREGATOR", "VDQMPORT",
        configEntry);

      ex.getMessage() << "Invalid configuration entry: "
        << ex.getEntryCategory() << " " << ex.getEntryName() << " "
        << ex.getEntryValue();

      throw ex;
    }
  }

  return port;
}


//------------------------------------------------------------------------------
// getRtcpdListenPort()
//------------------------------------------------------------------------------
int castor::tape::aggregator::AggregatorDaemon::getRtcpdListenPort()
  throw(castor::exception::InvalidConfigEntry) {
  int port = AGGREGATOR_RTCPDPORT; // Initialise to default value
  const char *const configEntry = getconfent("TAPEAGGREGATOR", "RTCPDPORT", 0);

  if(configEntry != NULL) {
    if(isAValidUInt(configEntry)) {
      port = atoi(configEntry);
    } else {
      castor::exception::InvalidConfigEntry ex("TAPEAGGREGATOR", "RTCPDPORT",
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
        configEntry);

      ex.getMessage() << "Invalid configuration entry: "
        << ex.getEntryCategory() << " " << ex.getEntryName() << " "
        << ex.getEntryValue();

      throw ex;
    }
  }

  return port;
}


//------------------------------------------------------------------------------
// isAValidUInt
//------------------------------------------------------------------------------
286
bool castor::tape::aggregator::AggregatorDaemon::isAValidUInt(const char *str)
287
  throw() {
288
289
290
291
292
293
294
295
296
297
298
299
300
301
  // 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;
302
}