23 #include <netcomm/fawkes/client.h>
24 #include <config/netconf.h>
25 #include <config/change_handler.h>
26 #include <utils/system/argparser.h>
27 #include <utils/system/signal.h>
34 using namespace fawkes;
51 this->config = config;
56 virtual void handle_signal(
int signal)
62 virtual void config_tag_changed(
const char *new_tag)
64 printf(
"--> New tag loaded: %s\n", new_tag);
69 printf(
"%s %-55s| %-8s| %-14s\n", v->
is_default() ?
"*" :
" ",
75 printf(
"%s %s: %s\n", v->
is_default() ?
"C" :
"c",
79 virtual void config_value_erased(
const char *path)
81 printf(
" %-55s| %-8s| %-14s\n", path,
"",
"ERASED");
92 c->wait(FAWKES_CID_CONFIGMANAGER);
108 printf(
"D %-55s| %-8s| %-14s\n",
"Path",
"Type",
"Value");
109 printf(
"--------------------------------------------------------------------------------------\n");
122 }
else if ( i->
is_int() ) {
134 printf(
"C %-55s: %s\n", i->
path(), comment.c_str());
152 }
else if ( i->
is_int() ) {
153 printf(
"%-14i\n", i->
get_int());
155 printf(
"%-14s\n", (i->
get_bool() ?
"true" :
"false"));
163 print_usage(
const char *program_name)
165 std::cout <<
"Usage: " << program_name <<
" [options] <cmd>" << std::endl
166 <<
"where cmd is one of the following:" << std::endl << std::endl
167 <<
" list" << std::endl
168 <<
" List all configuration items" << std::endl << std::endl
169 <<
" watch" << std::endl
170 <<
" Watch configuration changes" << std::endl << std::endl
171 <<
" get <path>" << std::endl
172 <<
" Get value for the given path" << std::endl << std::endl
173 <<
" set <path> <value> [type]" << std::endl
174 <<
" Set value for the given path to the given type and value" << std::endl
175 <<
" where type is one of float/uint/int/bool/string. The type" << std::endl
176 <<
" is only necessary if you are creating a new value" << std::endl << std::endl
177 <<
" set_default <path> <value> [type]" << std::endl
178 <<
" Set default value for the given path to the given type and value" << std::endl
179 <<
" where type is one of float/uint/int/bool/string. The type" << std::endl
180 <<
" is only necessary if you are creating a new value" << std::endl << std::endl
181 <<
" set_comment <path> <comment>" << std::endl
182 <<
" Set comment for the given path to the given value. The value at" << std::endl
183 <<
" the given path must already exist in the host-specific configuration." << std::endl << std::endl
184 <<
" set_default_comment <path> <comment>" << std::endl
185 <<
" Set default comment for the given path to the given value. The value at" << std::endl
186 <<
" the given path must already exist in the default configuration." << std::endl << std::endl
187 <<
" erase <path>" << std::endl
188 <<
" Erase value for given path from config" << std::endl
189 <<
" erase_default <path>" << std::endl
190 <<
" Erase default value for given path from config" << std::endl << std::endl
191 <<
"and options is none, one or more of the following:" << std::endl << std::endl
192 <<
" -c Show comments (only available with list and watch cmd)" << std::endl
193 <<
" -a Show all values, even double if default and host-specific " << std::endl
194 <<
" values exist (only available with list)" << std::endl
195 <<
" -q Quiet. Only show important output, suitable for parsing. " << std::endl
196 <<
" (not supported for all commands yet) " << std::endl
197 <<
" -r host[:port] Remote host (and optionally port) to connect to\n" << std::endl
206 main(
int argc,
char **argv)
210 if ( argp.has_arg(
"h") ) {
211 print_usage(argv[0]);
215 std::string host =
"localhost";
216 unsigned short int port = 1910;
217 if ( argp.has_arg(
"r") ) {
218 argp.parse_hostport(
"r", host, port);
222 if ( argp.has_arg(
"q") ) {
232 printf(
"Could not connect to host: %s\n", host.c_str());
238 const std::vector< const char* > & args = argp.items();
240 if ( args.size() == 0) {
242 printf(
"Not enough args\n\n");
243 print_usage(argv[0]);
244 }
else if (strcmp(
"get", args[0]) == 0) {
245 if (args.size() == 2) {
247 printf(
"Requesting value %s\n", args[1]);
258 printf(
"No such value found!\n");
263 printf(
"You must supply path argument\n");
265 }
else if ((strcmp(
"set", args[0]) == 0) || (strcmp(
"set_default", args[0]) == 0)) {
266 bool set_def = (strcmp(
"set_default", args[0]) == 0);
267 if (args.size() >= 3) {
269 printf(
"Requesting old value for %s\n", args[1]);
276 printf(
"Value does not currently exist in configuration.\n");
279 std::string desired_type =
"";
280 if (args.size() == 4) {
282 desired_type = args[3];
285 if ( (desired_type ==
"") && ! i->
valid()) {
286 printf(
"Please specify type\n");
288 }
else if ( (desired_type !=
"") && (i->
valid() && (desired_type != i->
type())) ) {
289 printf(
"The given type '%s' contradicts with type '%s' in config. "
290 "Erase before setting with new type.\n", desired_type.c_str(), i->
type());
293 if ( i->
valid() ) desired_type = i->
type();
295 if ( desired_type ==
"float" ) {
297 float f = strtod(args[2], &endptr);
298 if ( endptr[0] != 0 ) {
299 printf(
"ERROR: '%s' is not a float\n", args[2]);
307 }
else if ( (desired_type ==
"unsigned int") || (desired_type ==
"uint") ) {
309 long int li = strtol(args[2], &endptr, 10);
310 if ( (endptr[0] != 0) || (li < 0) ) {
311 printf(
"ERROR: '%s' is not an unsigned int\n", args[2]);
319 }
else if ( desired_type ==
"int" ) {
321 long int li = strtol(args[2], &endptr, 10);
322 if ( endptr[0] != 0 ) {
323 printf(
"ERROR: '%s' is not an int\n", args[2]);
331 }
else if ( desired_type ==
"bool" ) {
334 if ( strcasecmp(
"true", args[2]) == 0 ) {
337 }
else if ( strcasecmp(
"false", args[2]) == 0 ) {
341 printf(
"ERROR: '%s' is not a boolean.\n", args[2]);
350 }
else if ( desired_type ==
"string" ) {
357 printf(
"Invalid type: %s\n", desired_type.c_str());
367 printf(
"ERROR: value does not exist\n");
373 printf(
"Usage: %s set <path> <value> [type]\n", argp.program_name());
375 }
else if ((strcmp(
"set_comment", args[0]) == 0) ||
376 (strcmp(
"set_default_comment", args[0]) == 0)) {
377 bool set_def = (strcmp(
"set_default_comment", args[0]) == 0);
378 if (args.size() >= 3) {
388 printf(
"Usage: %s set_(default_)comment <path> <value>\n", argp.program_name());
390 }
else if ((strcmp(
"erase", args[0]) == 0) || (strcmp(
"erase_default", args[0]) == 0)) {
391 bool erase_def = (strcmp(
"erase_default", args[0]) == 0);
392 if (args.size() == 2) {
393 printf(
"Erasing %svalue %s\n", (erase_def ?
"default " :
""), args[1]);
401 printf(
"No such value found!\n");
408 netconf->
erase(args[1]);
412 printf(
"Failed to erase %s (default vs. non-default?)\n", args[1]);
414 printf(
"Successfully erased %s\n", args[1]);
420 printf(
"You must supply path argument\n");
422 }
else if (strcmp(
"watch", args[0]) == 0) {
432 while ( i->
next() ) {
433 print_line(i, argp.has_arg(
"c"));
437 printf(
"------------------------------------------------------------------------------------\n");
438 printf(
"Modifications since watching:\n");
439 printf(
"------------------------------------------------------------------------------------\n");
442 }
else if (strcmp(
"list", args[0]) == 0) {
443 printf(
"Transmitting config from host... ");
454 bool show_comments = argp.has_arg(
"c");
455 if (argp.has_arg(
"a")) {
456 printf(
"DEFAULT ENTRIES\n");
458 while ( i->
next() ) {
459 print_line(i, show_comments);
462 printf(
"HOST-SPECIFIC ENTRIES\n");
464 while ( i->
next() ) {
465 print_line(i, show_comments);
470 while ( i->
next() ) {
471 print_line(i, show_comments);
479 printf(
"Cleaning up... ");