/* SPDX-License-Identifier: LGPL-2.1-only */
/*
 * src/utils.c		Utilities
 *
 *	This library is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU Lesser General Public
 *	License as published by the Free Software Foundation version 2.1
 *	of the License.
 *
 * Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
 */

/**
 * @defgroup cli Command Line Interface API
 *
 * @{
 *
 * These modules provide an interface for text based applications. The
 * functions provided are wrappers for their libnl equivalent with
 * added error handling. The functions check for allocation failures,
 * invalid input, and unknown types and will print error messages
 * accordingly via nl_cli_fatal().
 */

#include <netlink/cli/utils.h>
#include <locale.h>

#include "lib/defs.h"

#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif

/**
 * Parse a text based 32 bit unsigned integer argument
 * @arg arg		Integer in text form.
 *
 * Tries to convert the number provided in arg to a uint32_t. Will call
 * nl_cli_fatal() if the conversion fails.
 *
 * @return 32bit unsigned integer.
 */
uint32_t nl_cli_parse_u32(const char *arg)
{
	unsigned long lval;
	char *endptr;

	lval = strtoul(arg, &endptr, 0);
	if (endptr == arg || lval == ULONG_MAX)
		nl_cli_fatal(EINVAL, "Unable to parse \"%s\", not a number.",
			     arg);

	return (uint32_t) lval;
}

void nl_cli_print_version(void)
{
	printf("libnl tools version %s\n", LIBNL_VERSION);
	printf(
	"Copyright (C) 2003-2010 Thomas Graf <tgraf@redhat.com>\n"
	"\n"
	"This program comes with ABSOLUTELY NO WARRANTY. This is free \n"
	"software, and you are welcome to redistribute it under certain\n"
	"conditions. See the GNU General Public License for details.\n"
	);

	exit(0);
}

/**
 * Print error message and quit application
 * @arg err		Error code.
 * @arg fmt		Error message.
 *
 * Prints the formatted error message to stderr and quits the application
 * using the provided error code.
 */
void nl_cli_fatal(int err, const char *fmt, ...)
{
	va_list ap;

	fprintf(stderr, "Error: ");

	if (fmt) {
		va_start(ap, fmt);
		vfprintf(stderr, fmt, ap);
		va_end(ap);
		fprintf(stderr, "\n");
	} else {
		char *buf;
#ifdef HAVE_STRERROR_L
		locale_t loc = newlocale(LC_MESSAGES_MASK, "", (locale_t)0);
		if (loc == (locale_t)0) {
			if (errno == ENOENT)
				loc = newlocale(LC_MESSAGES_MASK,
						"POSIX", (locale_t)0);
			if (loc == (locale_t)0)
				buf = "newlocale() failed";
		}
		if (loc != (locale_t)0)
			buf = strerror_l(err, loc);
#else
		buf = strerror(err);
#endif
		fprintf(stderr, "%s\n", buf);
#ifdef HAVE_STRERROR_L
		if (loc != (locale_t)0)
			freelocale(loc);
#endif
	}

	exit(abs(err));
}

int nl_cli_connect(struct nl_sock *sk, int protocol)
{
	int err;

	if ((err = nl_connect(sk, protocol)) < 0)
		nl_cli_fatal(err, "Unable to connect netlink socket: %s",
			     nl_geterror(err));

	return err;
}

struct nl_sock *nl_cli_alloc_socket(void)
{
	struct nl_sock *sock;

	if (!(sock = nl_socket_alloc()))
		nl_cli_fatal(ENOBUFS, "Unable to allocate netlink socket");

	return sock;
}

struct nl_addr *nl_cli_addr_parse(const char *str, int family)
{
	struct nl_addr *addr;
	int err;

	if ((err = nl_addr_parse(str, family, &addr)) < 0)
		nl_cli_fatal(err, "Unable to parse address \"%s\": %s",
			     str, nl_geterror(err));

	return addr;
}

int nl_cli_parse_dumptype(const char *str)
{
	if (!strcasecmp(str, "brief"))
		return NL_DUMP_LINE;
	else if (!strcasecmp(str, "details") || !strcasecmp(str, "detailed"))
		return NL_DUMP_DETAILS;
	else if (!strcasecmp(str, "stats"))
		return NL_DUMP_STATS;
	else
		nl_cli_fatal(EINVAL, "Invalid dump type \"%s\".\n", str);

	return 0;
}

int nl_cli_confirm(struct nl_object *obj, struct nl_dump_params *params,
		   int default_yes)
{
	nl_object_dump(obj, params);

	for (;;) {
		char buf[32] = { 0 };
		int answer;

		printf("Delete? (%c/%c) ",
			default_yes ? 'Y' : 'y',
			default_yes ? 'n' : 'N');

		if (!fgets(buf, sizeof(buf), stdin)) {
			fprintf(stderr, "Error while reading\n.");
			continue;
		}

		switch ((answer = tolower(buf[0]))) {
		case '\n':
			answer = default_yes ? 'y' : 'n';
			/* fall through */
		case 'y':
		case 'n':
			return answer == 'y';
		}

		fprintf(stderr, "Invalid input, try again.\n");
	}

	return 0;

}

struct nl_cache *nl_cli_alloc_cache(struct nl_sock *sock, const char *name,
			    int (*ac)(struct nl_sock *, struct nl_cache **))
{
	struct nl_cache *cache;
	int err;

	if ((err = ac(sock, &cache)) < 0)
		nl_cli_fatal(err, "Unable to allocate %s cache: %s",
			     name, nl_geterror(err));

	nl_cache_mngt_provide(cache);

	return cache;
}

struct nl_cache *nl_cli_alloc_cache_flags(struct nl_sock *sock,
			    const char *name, unsigned int flags,
			    int (*ac)(struct nl_sock *, struct nl_cache **,
				      unsigned int))
{
	struct nl_cache *cache;
	int err;

	if ((err = ac(sock, &cache, flags)) < 0)
		nl_cli_fatal(err, "Unable to allocate %s cache: %s",
			     name, nl_geterror(err));

	nl_cache_mngt_provide(cache);

	return cache;
}

void nl_cli_load_module(const char *prefix, const char *name)
{
	char path[FILENAME_MAX+1];

	snprintf(path, sizeof(path), "%s/%s/%s.so",
		 PKGLIBDIR, prefix, name);

#ifdef HAVE_DLFCN_H
	{
		void *handle;

		if (!(handle = dlopen(path, RTLD_NOW))) {
			nl_cli_fatal(ENOENT, "Unable to load module \"%s\": %s\n",
			             path, dlerror());
		}
	}
#else
	nl_cli_fatal(ENOTSUP, "Unable to load module \"%s\": built without dynamic libraries support\n",
	             path);
#endif
}

/** @} */
