lfc_controller.cc 6.63 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 132 133 134 135
            exit(EXIT_SUCCESS);

        case '?':
            // Unknown argument
            isc_throw(InvalidUsage, "Unknown argument");

        case ':':
            // Missing option argument
            isc_throw(InvalidUsage, "Missing option argument");
136 137

        default:
138 139 140
            // I don't think we should get here as the unknown arguments
            // and missing options cases should cover everything else
            isc_throw(InvalidUsage, "Invalid command line");
Shawn Routhier's avatar
Shawn Routhier committed
141
        }
142 143 144 145 146 147 148
    }

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

149
    if (protocol_version_ == 0) {
150 151 152 153
        isc_throw(InvalidUsage, "DHCP version required");
    }

    if (previous_file_.empty()) {
Shawn Routhier's avatar
Shawn Routhier committed
154
        isc_throw(InvalidUsage, "Previous file not specified");
155 156 157
    }

    if (copy_file_.empty()) {
Shawn Routhier's avatar
Shawn Routhier committed
158
        isc_throw(InvalidUsage, "Copy file not specified");
159 160 161
    }

    if (output_file_.empty()) {
Shawn Routhier's avatar
Shawn Routhier committed
162
        isc_throw(InvalidUsage, "Output file not specified");
163 164
    }

165
    if (finish_file_.empty()) {
Shawn Routhier's avatar
Shawn Routhier committed
166
        isc_throw(InvalidUsage, "Finish file not specified");
167 168
    }

169
    if (config_file_.empty()) {
Shawn Routhier's avatar
Shawn Routhier committed
170
        isc_throw(InvalidUsage, "Config file not specified");
171 172 173 174
    }

    // If verbose is set echo the input information
    if (verbose_ == true) {
175
      std::cerr << "Protocol version:    DHCPv" << protocol_version_ << std::endl
Shawn Routhier's avatar
Shawn Routhier committed
176 177 178 179 180 181
                << "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;
182 183 184 185
    }
}

void
186
LFCController::usage(const std::string& text) {
187 188 189 190 191
    if (text != "") {
        std::cerr << "Usage error: " << text << std::endl;
    }

    std::cerr << "Usage: " << lfc_bin_name_ << std::endl
192
              << " [-4|-6] -p file -i file -o file -f file -c file" << std::endl
193 194 195 196
              << "   -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
197
              << "   -f <file>: finish file" << std::endl
198 199 200 201
              << "   -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
202
              << "   -h: print this message " << std::endl
203 204 205
              << std::endl;
}

206
std::string
207 208
LFCController::getVersion(const bool extended) const{
    std::stringstream version_stream;
209

210
    version_stream << VERSION;
211
    if (extended) {
212
        version_stream << std::endl << EXTENDED_VERSION;
213 214
    }

215
    return (version_stream.str());
216 217
}

218 219
}; // namespace isc::lfc
}; // namespace isc