lfc_controller.cc 6.29 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// Copyright (C) 2015  Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

15
#include <lfc/lfc_controller.h>
16
#include <exceptions/exceptions.h>
Shawn Routhier's avatar
Shawn Routhier committed
17
#include <config.h>
18
#include <iostream>
19 20
#include <sstream>
#include <unistd.h>
21 22 23 24 25 26 27 28

using namespace std;

namespace isc {
namespace lfc {

/// @brief Defines the application name, it may be used to locate
/// configuration data and appears in log statements.
29
const char* LFCController::lfc_app_name_ = "DhcpLFC";
30 31

/// @brief Defines the executable name.
32
const char* LFCController::lfc_bin_name_ = "kea-lfc";
33

34
LFCController::LFCController()
35
    : protocol_version_(0), verbose_(false), config_file_(""), previous_file_(""),
Shawn Routhier's avatar
Shawn Routhier committed
36
      copy_file_(""), output_file_(""), finish_file_(""), pid_file_("") {
37 38
}

39
LFCController::~LFCController() {
40 41 42
}

void
43
LFCController::launch(int argc, char* argv[]) {
44 45 46 47 48 49 50 51 52
  try {
    parseArgs(argc, argv);
  } catch (const InvalidUsage& ex) {
    usage(ex.what());
    throw;  // rethrow it
  }
}

void
53
LFCController::parseArgs(int argc, char* argv[]) {
54 55
    int ch;

56 57
    opterr = 0;
    optind = 1;
58
    while ((ch = getopt(argc, argv, "46dvVp:i:o:c:f:")) != -1) {
59
        switch (ch) {
Shawn Routhier's avatar
Shawn Routhier committed
60
        case '4':
61
            // Process DHCPv4 lease files.
62
            protocol_version_ = 4;
63 64
            break;

Shawn Routhier's avatar
Shawn Routhier committed
65
        case '6':
66
            // Process DHCPv6 lease files.
67
            protocol_version_ = 6;
68 69
            break;

Shawn Routhier's avatar
Shawn Routhier committed
70
        case 'v':
71
            // Print just Kea vesion and exit.
Shawn Routhier's avatar
Shawn Routhier committed
72
            std::cout << getVersion(false) << std::endl;
73 74
            exit(EXIT_SUCCESS);

Shawn Routhier's avatar
Shawn Routhier committed
75
        case 'V':
76
            // Print extended  Kea vesion and exit.
Shawn Routhier's avatar
Shawn Routhier committed
77
            std::cout << getVersion(true) << std::endl;
78 79
            exit(EXIT_SUCCESS);

Shawn Routhier's avatar
Shawn Routhier committed
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
        case 'd':
            // Verbose output.
            verbose_ = true;
            break;

        case 'p':
            // Previous file name.
            if (optarg == NULL) {
                isc_throw(InvalidUsage, "Previous file name missing");
            }
            previous_file_ = optarg;
            break;

        case 'i':
            // Copy file name.
            if (optarg == NULL) {
                isc_throw(InvalidUsage, "Copy file name missing");
            }
            copy_file_ = optarg;
            break;

        case 'o':
            // Output file name.
            if (optarg == NULL) {
                isc_throw(InvalidUsage, "Output file name missing");
            }
            output_file_ = optarg;
            break;

        case 'f':
            // Output file name.
            if (optarg == NULL) {
                isc_throw(InvalidUsage, "Finish file name missing");
            }
            finish_file_ = optarg;
            break;

        case 'c':
            // Previous file name.
            if (optarg == NULL) {
                isc_throw(InvalidUsage, "Configuration file name missing");
            }
            config_file_ = optarg;
            break;

125
        case 'h':
Shawn Routhier's avatar
Shawn Routhier committed
126
            usage("");
127 128 129 130 131
            return;

        default:
            // We should never actually get here
            isc_throw(InvalidUsage, "Illegal result.");
Shawn Routhier's avatar
Shawn Routhier committed
132
        }
133 134 135 136 137 138 139
    }

    // Check for extraneous parameters.
    if (argc > optind) {
        isc_throw(InvalidUsage, "Extraneous parameters.");
    }

140
    if (protocol_version_ == 0) {
141 142 143 144
        isc_throw(InvalidUsage, "DHCP version required");
    }

    if (previous_file_.empty()) {
Shawn Routhier's avatar
Shawn Routhier committed
145
        isc_throw(InvalidUsage, "Previous file not specified");
146 147 148
    }

    if (copy_file_.empty()) {
Shawn Routhier's avatar
Shawn Routhier committed
149
        isc_throw(InvalidUsage, "Copy file not specified");
150 151 152
    }

    if (output_file_.empty()) {
Shawn Routhier's avatar
Shawn Routhier committed
153
        isc_throw(InvalidUsage, "Output file not specified");
154 155
    }

156
    if (finish_file_.empty()) {
Shawn Routhier's avatar
Shawn Routhier committed
157
        isc_throw(InvalidUsage, "Finish file not specified");
158 159
    }

160
    if (config_file_.empty()) {
Shawn Routhier's avatar
Shawn Routhier committed
161
        isc_throw(InvalidUsage, "Config file not specified");
162 163 164 165
    }

    // If verbose is set echo the input information
    if (verbose_ == true) {
166
      std::cerr << "Protocol version:    DHCPv" << protocol_version_ << std::endl
Shawn Routhier's avatar
Shawn Routhier committed
167 168 169 170 171 172
                << "Previous lease file: " << previous_file_ << std::endl
                << "Copy lease file:     " << copy_file_ << std::endl
                << "Output lease file:   " << output_file_ << std::endl
                << "Finishn file:        " << finish_file_ << std::endl
                << "Config file:         " << config_file_ << std::endl
                << "PID file:            " << pid_file_ << std::endl;
173 174 175 176
    }
}

void
177
LFCController::usage(const std::string& text) {
178 179 180 181 182
    if (text != "") {
        std::cerr << "Usage error: " << text << std::endl;
    }

    std::cerr << "Usage: " << lfc_bin_name_ << std::endl
183
              << " [-4|-6] -p file -i file -o file -f file -c file" << std::endl
184 185 186 187
              << "   -4 or -6 clean a set of v4 or v6 lease files" << std::endl
              << "   -p <file>: previous lease file" << std::endl
              << "   -i <file>: copy of lease file" << std::endl
              << "   -o <file>: output lease file" << std::endl
188
              << "   -f <file>: finish file" << std::endl
189 190 191 192
              << "   -c <file>: configuration file" << std::endl
              << "   -v: print version number and exit" << std::endl
              << "   -V: print extended version inforamtion and exit" << std::endl
              << "   -d: optional, verbose output " << std::endl
193
              << "   -h: print this message " << std::endl
194 195 196
              << std::endl;
}

197
std::string
198 199
LFCController::getVersion(const bool extended) const{
    std::stringstream version_stream;
200

201
    version_stream << VERSION;
202
    if (extended) {
203
        version_stream << std::endl << EXTENDED_VERSION;
204 205
    }

206
    return (version_stream.str());
207 208
}

209 210
}; // namespace isc::lfc
}; // namespace isc