/
auroraos
/
mirror_libnl
Обзор
Документация
Войти
/
auroraos
/
mirror_libnl
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
main
src/lib/utils.c
246 строк
5 KB
Thomas Haller
build: move "-DPGKLIBDIR" and rename
29 май 2024, 17:45
Не верифицирован
29 май 2024, 17:45
20664e1
Код
Авторство
О чём код?
/* SPDX-License-Identifier: LGPL-2.1-only */ /* * 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 "nl-default.h" #include <locale.h> #ifdef HAVE_DLFCN_H #include <dlfcn.h> #endif #include <netlink/cli/utils.h> /** * 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", _NL_PKGLIBDIR, prefix, name); #ifdef HAVE_DLFCN_H { void *handle; handle = dlopen(path, RTLD_NOW); if (!handle) { nl_cli_fatal(ENOENT, "Unable to load module \"%s\": %s\n", path, dlerror()); } /* We intentionally leak the dlopen handle. */ /* coverity[RESOURCE_LEAK] */ } #else nl_cli_fatal(ENOTSUP, "Unable to load module \"%s\": built without dynamic libraries support\n", path); #endif } /** @} */