diff options
Diffstat (limited to '')
-rw-r--r-- | util/argconfig.c | 31 | ||||
-rw-r--r-- | util/argconfig.h | 4 | ||||
-rw-r--r-- | util/cleanup.c | 4 | ||||
-rw-r--r-- | util/cleanup.h | 18 | ||||
-rw-r--r-- | util/json.c | 26 | ||||
-rw-r--r-- | util/json.h | 17 | ||||
-rw-r--r-- | util/log.c | 90 | ||||
-rw-r--r-- | util/log.h | 34 |
8 files changed, 188 insertions, 36 deletions
diff --git a/util/argconfig.c b/util/argconfig.c index f647448..341a049 100644 --- a/util/argconfig.c +++ b/util/argconfig.c @@ -31,13 +31,14 @@ #include "argconfig.h" #include "suffix.h" -#include <string.h> +#include <errno.h> +#include <inttypes.h> #include <getopt.h> +#include <limits.h> #include <stdio.h> #include <stdlib.h> -#include <errno.h> #include <stdarg.h> -#include <inttypes.h> +#include <string.h> static argconfig_help_func *help_funcs[MAX_HELP_FUNC] = { NULL }; @@ -450,10 +451,11 @@ int argconfig_parse_subopt_string(char *string, char **options, return 0; } -unsigned argconfig_parse_comma_sep_array(char *string, int *val, +int argconfig_parse_comma_sep_array(char *string, int *val, unsigned max_length) { - unsigned ret = 0; + int ret = 0; + unsigned long v; char *tmp; char *p; @@ -464,9 +466,14 @@ unsigned argconfig_parse_comma_sep_array(char *string, int *val, if (!tmp) return 0; - val[ret] = strtol(tmp, &p, 0); + v = strtoul(tmp, &p, 0); if (*p != 0) return -1; + if (v > UINT_MAX) { + fprintf(stderr, "%s out of range\n", tmp); + return -1; + } + val[ret] = v; ret++; while (1) { @@ -478,19 +485,23 @@ unsigned argconfig_parse_comma_sep_array(char *string, int *val, if (ret >= max_length) return -1; - val[ret] = strtol(tmp, &p, 0); - + v = strtoul(tmp, &p, 0); if (*p != 0) return -1; + if (v > UINT_MAX) { + fprintf(stderr, "%s out of range\n", tmp); + return -1; + } + val[ret] = v; ret++; } } -unsigned argconfig_parse_comma_sep_array_long(char *string, +int argconfig_parse_comma_sep_array_long(char *string, unsigned long long *val, unsigned max_length) { - unsigned ret = 0; + int ret = 0; char *tmp; char *p; diff --git a/util/argconfig.h b/util/argconfig.h index 623b832..3147277 100644 --- a/util/argconfig.h +++ b/util/argconfig.h @@ -119,9 +119,9 @@ int argconfig_parse(int argc, char *argv[], const char *program_desc, const struct argconfig_commandline_options *options); int argconfig_parse_subopt_string(char *string, char **options, size_t max_options); -unsigned argconfig_parse_comma_sep_array(char *string, int *ret, +int argconfig_parse_comma_sep_array(char *string, int *ret, unsigned max_length); -unsigned argconfig_parse_comma_sep_array_long(char *string, +int argconfig_parse_comma_sep_array_long(char *string, unsigned long long *ret, unsigned max_length); void argconfig_register_help_func(argconfig_help_func * f); diff --git a/util/cleanup.c b/util/cleanup.c new file mode 100644 index 0000000..0d5d910 --- /dev/null +++ b/util/cleanup.c @@ -0,0 +1,4 @@ +#include <stdlib.h> +#include "cleanup.h" + +DEFINE_CLEANUP_FUNC(cleanup_charp, char *, free); diff --git a/util/cleanup.h b/util/cleanup.h new file mode 100644 index 0000000..89a4984 --- /dev/null +++ b/util/cleanup.h @@ -0,0 +1,18 @@ +#ifndef __CLEANUP_H +#define __CLEANUP_H + +#define __cleanup__(fn) __attribute__((cleanup(fn))) + +#define DECLARE_CLEANUP_FUNC(name, type) \ + void name(type *__p) + +#define DEFINE_CLEANUP_FUNC(name, type, free_fn)\ +DECLARE_CLEANUP_FUNC(name, type) \ +{ \ + if (*__p) \ + free_fn(*__p); \ +} + +DECLARE_CLEANUP_FUNC(cleanup_charp, char *); + +#endif diff --git a/util/json.c b/util/json.c index 2978410..df0aefb 100644 --- a/util/json.c +++ b/util/json.c @@ -19,9 +19,9 @@ struct json_object *json_create_object(void) return test; } -struct json_array *json_create_array(void) +struct json_object *json_create_array(void) { - void *test = calloc(1, sizeof(struct json_array)); + void *test = calloc(1, sizeof(struct json_object)); if (!test) fail_and_notify(); return test; @@ -146,7 +146,7 @@ static struct json_value *json_create_value_object(struct json_object *obj) return value; } -static struct json_value *json_create_value_array(struct json_array *array) +static struct json_value *json_create_value_array(struct json_object *array) { struct json_value *value = malloc(sizeof(struct json_value)); @@ -173,7 +173,7 @@ void json_free_object(struct json_object *obj) free(obj); } -void json_free_array(struct json_array *array) +void json_free_array(struct json_object *array) { int i; @@ -206,7 +206,7 @@ static void json_free_value(struct json_value *value) free(value); } -static int json_array_add_value(struct json_array *array, struct json_value *value) +static int json_array_add_value(struct json_object *array, struct json_value *value) { struct json_value **values = realloc(array->values, sizeof(struct json_value *) * (array->value_cnt + 1)); @@ -255,7 +255,7 @@ int json_object_add_value_type(struct json_object *obj, const char *name, int ty else if (type == JSON_TYPE_OBJECT) value = json_create_value_object(va_arg(args, struct json_object *)); else - value = json_create_value_array(va_arg(args, struct json_array *)); + value = json_create_value_array(va_arg(args, struct json_object *)); va_end(args); if (!value) @@ -274,8 +274,8 @@ int json_object_add_value_type(struct json_object *obj, const char *name, int ty return 0; } -static void json_print_array(struct json_array *array, void *); -int json_array_add_value_type(struct json_array *array, int type, ...) +static void json_print_array(struct json_object *array, void *); +int json_array_add_value_type(struct json_object *array, int type, ...) { struct json_value *value; va_list args; @@ -293,7 +293,7 @@ int json_array_add_value_type(struct json_array *array, int type, ...) else if (type == JSON_TYPE_OBJECT) value = json_create_value_object(va_arg(args, struct json_object *)); else - value = json_create_value_array(va_arg(args, struct json_array *)); + value = json_create_value_array(va_arg(args, struct json_object *)); va_end(args); if (!value) @@ -309,7 +309,7 @@ int json_array_add_value_type(struct json_array *array, int type, ...) static int json_value_level(struct json_value *value); static int json_pair_level(struct json_pair *pair); -static int json_array_level(struct json_array *array); +static int json_array_level(struct json_object *array); static int json_object_level(struct json_object *object) { if (object->parent == NULL) @@ -322,7 +322,7 @@ static int json_pair_level(struct json_pair *pair) return json_object_level(pair->parent) + 1; } -static int json_array_level(struct json_array *array) +static int json_array_level(struct json_object *array) { return json_value_level(array->parent); } @@ -342,7 +342,7 @@ static void json_print_level(int level, void *out) } static void json_print_pair(struct json_pair *pair, void *); -static void json_print_array(struct json_array *array, void *); +static void json_print_array(struct json_object *array, void *); static void json_print_value(struct json_value *value, void *); void json_print_object(struct json_object *obj, void *out) { @@ -366,7 +366,7 @@ static void json_print_pair(struct json_pair *pair, void *out) json_print_value(pair->value, out); } -static void json_print_array(struct json_array *array, void *out) +static void json_print_array(struct json_object *array, void *out) { int i; diff --git a/util/json.h b/util/json.h index d78d3db..666c78d 100644 --- a/util/json.h +++ b/util/json.h @@ -2,7 +2,6 @@ #define __JSON__H struct json_object; -struct json_array; struct json_pair; #define JSON_TYPE_STRING 0 @@ -21,22 +20,18 @@ struct json_value { long double float_number; char *string; struct json_object *object; - struct json_array *array; + struct json_object *array; }; int parent_type; union { struct json_pair *parent_pair; - struct json_array *parent_array; + struct json_object *parent_array; }; }; -struct json_array { +struct json_object { struct json_value **values; int value_cnt; - struct json_value *parent; -}; - -struct json_object { struct json_pair **pairs; int pair_cnt; struct json_value *parent; @@ -49,10 +44,10 @@ struct json_pair { }; struct json_object *json_create_object(void); -struct json_array *json_create_array(void); +struct json_object *json_create_array(void); void json_free_object(struct json_object *obj); -void json_free_array(struct json_array *array); +void json_free_array(struct json_object *array); int json_object_add_value_type(struct json_object *obj, const char *name, int type, ...); #define json_object_add_value_int(obj, name, val) \ @@ -67,7 +62,7 @@ int json_object_add_value_type(struct json_object *obj, const char *name, int ty json_object_add_value_type((obj), name, JSON_TYPE_OBJECT, (val)) #define json_object_add_value_array(obj, name, val) \ json_object_add_value_type((obj), name, JSON_TYPE_ARRAY, (val)) -int json_array_add_value_type(struct json_array *array, int type, ...); +int json_array_add_value_type(struct json_object *array, int type, ...); #define json_array_add_value_int(obj, val) \ json_array_add_value_type((obj), JSON_TYPE_INTEGER, (val)) #define json_array_add_value_uint(obj, val) \ diff --git a/util/log.c b/util/log.c new file mode 100644 index 0000000..4a22354 --- /dev/null +++ b/util/log.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2021 SUSE LLC + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This file implements basic logging functionality. + */ + +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <stdbool.h> +#include <syslog.h> +#include <unistd.h> +#include <time.h> +#define LOG_FUNCNAME 1 +#include "log.h" +#include "cleanup.h" + +#ifndef LOG_CLOCK +#define LOG_CLOCK CLOCK_MONOTONIC +#endif + +int log_level = DEFAULT_LOGLEVEL; +bool log_timestamp; +bool log_pid; + +void __attribute__((format(printf, 3, 4))) +__msg(int lvl, const char *func, const char *format, ...) +{ + va_list ap; + char pidbuf[16]; + char timebuf[32]; + static const char *const formats[] = { + "%s%s%s", + "%s%s%s: ", + "%s<%s>%s ", + "%s<%s> %s: ", + "[%s] %s%s ", + "[%s]%s %s: ", + "[%s] <%s>%s ", + "[%s] <%s> %s: ", + }; + char *header __cleanup__(cleanup_charp) = NULL; + char *message __cleanup__(cleanup_charp) = NULL; + int idx; + + if (lvl > log_level) + return; + + if (log_timestamp) { + struct timespec now; + + clock_gettime(LOG_CLOCK, &now); + snprintf(timebuf, sizeof(timebuf), "%6ld.%06ld", + (long)now.tv_sec, now.tv_nsec / 1000); + } else + *timebuf = '\0'; + + if (log_pid) + snprintf(pidbuf, sizeof(pidbuf), "%ld", (long)getpid()); + else + *pidbuf = '\0'; + + idx = ((log_timestamp ? 1 : 0) << 2) | + ((log_pid ? 1 : 0) << 1) | (func ? 1 : 0); + + if (asprintf(&header, formats[idx], timebuf, pidbuf, func ? func : "") + == -1) + header = NULL; + + va_start(ap, format); + if (vasprintf(&message, format, ap) == -1) + message = NULL; + va_end(ap); + + fprintf(stderr, "%s%s", header ? header : "<error>", + message ? message : "<error>"); + +} diff --git a/util/log.h b/util/log.h new file mode 100644 index 0000000..15107a5 --- /dev/null +++ b/util/log.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021 Martin Wilck, SUSE LLC + * SPDX-License-Identifier: LGPL-2.1-or-newer + */ +#ifndef _LOG_H +#define _LOG_H + +#ifndef MAX_LOGLEVEL +# define MAX_LOGLEVEL LOG_DEBUG +#endif +#ifndef DEFAULT_LOGLEVEL +# define DEFAULT_LOGLEVEL LOG_NOTICE +#endif + +#if (LOG_FUNCNAME == 1) +#define _log_func __func__ +#else +#define _log_func NULL +#endif + +extern int log_level; +extern bool log_timestamp; +extern bool log_pid; + +void __attribute__((format(printf, 3, 4))) +__msg(int lvl, const char *func, const char *format, ...); + +#define msg(lvl, format, ...) \ + do { \ + if ((lvl) <= MAX_LOGLEVEL) \ + __msg(lvl, _log_func, format, ##__VA_ARGS__); \ + } while (0) + +#endif /* _LOG_H */ |