lfc_controller.cc 6.65 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
#include <stdlib.h>
22 23 24 25 26 27 28 29

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.
30
const char* LFCController::lfc_app_name_ = "DhcpLFC";
31 32

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

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

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

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

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

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

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

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

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

Shawn Routhier's avatar
Shawn Routhier committed
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 125
        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;

126
        case 'h':
Shawn Routhier's avatar
Shawn Routhier committed
127
            usage("");
128 129 130 131 132 133 134 135 136
            exit(EXIT_SUCCESS);

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

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

        default:
139 140 141
            // 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
142
        }
143 144 145 146 147 148 149
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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