144d362409d5469aed47d19e7908d19bd194493aThomas Graf/*
244d362409d5469aed47d19e7908d19bd194493aThomas Graf * src/utils.c		Utilities
344d362409d5469aed47d19e7908d19bd194493aThomas Graf *
444d362409d5469aed47d19e7908d19bd194493aThomas Graf *	This library is free software; you can redistribute it and/or
544d362409d5469aed47d19e7908d19bd194493aThomas Graf *	modify it under the terms of the GNU Lesser General Public
644d362409d5469aed47d19e7908d19bd194493aThomas Graf *	License as published by the Free Software Foundation version 2.1
744d362409d5469aed47d19e7908d19bd194493aThomas Graf *	of the License.
844d362409d5469aed47d19e7908d19bd194493aThomas Graf *
98808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf * Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
1044d362409d5469aed47d19e7908d19bd194493aThomas Graf */
1144d362409d5469aed47d19e7908d19bd194493aThomas Graf
128808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf/**
138808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf * @defgroup cli Command Line Interface API
148808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf *
158808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf * @{
168808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf */
1744d362409d5469aed47d19e7908d19bd194493aThomas Graf
188808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf#include <netlink/cli/utils.h>
1944d362409d5469aed47d19e7908d19bd194493aThomas Graf
208808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Grafuint32_t nl_cli_parse_u32(const char *arg)
2110cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf{
2210cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	unsigned long lval;
2310cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	char *endptr;
2410cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf
2510cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	lval = strtoul(arg, &endptr, 0);
2610cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	if (endptr == arg || lval == ULONG_MAX)
278808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		nl_cli_fatal(EINVAL, "Unable to parse \"%s\", not a number.",
288808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf			     arg);
2910cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf
3010cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	return (uint32_t) lval;
3110cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf}
3210cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf
338808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Grafvoid nl_cli_print_version(void)
345e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf{
355e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	printf("libnl tools version %s\n", LIBNL_VERSION);
365e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	printf(
378808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf	"Copyright (C) 2003-2009 Thomas Graf <tgraf@redhat.com>\n"
385e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	"\n"
395e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	"This program comes with ABSOLUTELY NO WARRANTY. This is free \n"
405e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	"software, and you are welcome to redistribute it under certain\n"
415e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	"conditions. See the GNU General Public License for details.\n"
425e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	);
435e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf
445e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	exit(0);
455e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf}
465e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf
478808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Grafvoid nl_cli_fatal(int err, const char *fmt, ...)
48535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf{
49535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	va_list ap;
50535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
51535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	fprintf(stderr, "Error: ");
52535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
538808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf	if (fmt) {
548808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		va_start(ap, fmt);
558808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		vfprintf(stderr, fmt, ap);
568808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		va_end(ap);
578808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		fprintf(stderr, "\n");
588808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf	} else
598808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		fprintf(stderr, "%s\n", strerror(err));
60535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
615e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	exit(abs(err));
62535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf}
63535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
648808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Grafint nl_cli_connect(struct nl_sock *sk, int protocol)
6544d362409d5469aed47d19e7908d19bd194493aThomas Graf{
6644d362409d5469aed47d19e7908d19bd194493aThomas Graf	int err;
6744d362409d5469aed47d19e7908d19bd194493aThomas Graf
685e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	if ((err = nl_connect(sk, protocol)) < 0)
698808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		nl_cli_fatal(err, "Unable to connect netlink socket: %s",
708808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf			     nl_geterror(err));
7144d362409d5469aed47d19e7908d19bd194493aThomas Graf
7244d362409d5469aed47d19e7908d19bd194493aThomas Graf	return err;
7344d362409d5469aed47d19e7908d19bd194493aThomas Graf}
7444d362409d5469aed47d19e7908d19bd194493aThomas Graf
758808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Grafstruct nl_sock *nl_cli_alloc_socket(void)
7644d362409d5469aed47d19e7908d19bd194493aThomas Graf{
775e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	struct nl_sock *sock;
78535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
795e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	if (!(sock = nl_socket_alloc()))
808808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		nl_cli_fatal(ENOBUFS, "Unable to allocate netlink socket");
81535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
82535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	return sock;
8344d362409d5469aed47d19e7908d19bd194493aThomas Graf}
8444d362409d5469aed47d19e7908d19bd194493aThomas Graf
858808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Grafstruct nl_addr *nl_cli_addr_parse(const char *str, int family)
8644d362409d5469aed47d19e7908d19bd194493aThomas Graf{
8744d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct nl_addr *addr;
885e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	int err;
8944d362409d5469aed47d19e7908d19bd194493aThomas Graf
905e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	if ((err = nl_addr_parse(str, family, &addr)) < 0)
918808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		nl_cli_fatal(err, "Unable to parse address \"%s\": %s",
928808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf			     str, nl_geterror(err));
9344d362409d5469aed47d19e7908d19bd194493aThomas Graf
9444d362409d5469aed47d19e7908d19bd194493aThomas Graf	return addr;
9544d362409d5469aed47d19e7908d19bd194493aThomas Graf}
9644d362409d5469aed47d19e7908d19bd194493aThomas Graf
978808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Grafint nl_cli_parse_dumptype(const char *str)
9844d362409d5469aed47d19e7908d19bd194493aThomas Graf{
9944d362409d5469aed47d19e7908d19bd194493aThomas Graf	if (!strcasecmp(str, "brief"))
100d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf		return NL_DUMP_LINE;
1016d9d3d54750c1d8a9c90c463cc1d58a447c98f64Thomas Graf	else if (!strcasecmp(str, "details") || !strcasecmp(str, "detailed"))
102d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf		return NL_DUMP_DETAILS;
10344d362409d5469aed47d19e7908d19bd194493aThomas Graf	else if (!strcasecmp(str, "stats"))
10444d362409d5469aed47d19e7908d19bd194493aThomas Graf		return NL_DUMP_STATS;
10544d362409d5469aed47d19e7908d19bd194493aThomas Graf	else if (!strcasecmp(str, "env"))
10644d362409d5469aed47d19e7908d19bd194493aThomas Graf		return NL_DUMP_ENV;
1075e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	else
1088808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		nl_cli_fatal(EINVAL, "Invalid dump type \"%s\".\n", str);
1095e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf
1105e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	return 0;
11144d362409d5469aed47d19e7908d19bd194493aThomas Graf}
11244d362409d5469aed47d19e7908d19bd194493aThomas Graf
1138808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Grafint nl_cli_confirm(struct nl_object *obj, struct nl_dump_params *params,
1148808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		   int default_yes)
11544d362409d5469aed47d19e7908d19bd194493aThomas Graf{
1165e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	int answer;
11744d362409d5469aed47d19e7908d19bd194493aThomas Graf
1185e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	nl_object_dump(obj, params);
1195e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	printf("Delete? (%c/%c) ",
1205e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf		default_yes ? 'Y' : 'y',
1215e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf		default_yes ? 'n' : 'N');
122535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
1235e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	do {
1245e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf		answer = tolower(getchar());
1255e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf		if (answer == '\n')
1265e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf			answer = default_yes ? 'y' : 'n';
1275e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	} while (answer != 'y' && answer != 'n');
12844d362409d5469aed47d19e7908d19bd194493aThomas Graf
1295e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	return answer == 'y';
13044d362409d5469aed47d19e7908d19bd194493aThomas Graf}
13144d362409d5469aed47d19e7908d19bd194493aThomas Graf
1328808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Grafstruct nl_cache *nl_cli_alloc_cache(struct nl_sock *sock, const char *name,
1338808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf			    int (*ac)(struct nl_sock *, struct nl_cache **))
13444d362409d5469aed47d19e7908d19bd194493aThomas Graf{
13544d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct nl_cache *cache;
1365e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	int err;
13744d362409d5469aed47d19e7908d19bd194493aThomas Graf
1385e732ad075e54ceb9f9e94fadbcec2e83d971b52Thomas Graf	if ((err = ac(sock, &cache)) < 0)
1398808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		nl_cli_fatal(err, "Unable to allocate %s cache: %s",
1408808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf			     name, nl_geterror(err));
141535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
142535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	nl_cache_mngt_provide(cache);
14344d362409d5469aed47d19e7908d19bd194493aThomas Graf
14444d362409d5469aed47d19e7908d19bd194493aThomas Graf	return cache;
14544d362409d5469aed47d19e7908d19bd194493aThomas Graf}
14644d362409d5469aed47d19e7908d19bd194493aThomas Graf
1478808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf/** @} */
148