summaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--util/argconfig.c31
-rw-r--r--util/argconfig.h4
-rw-r--r--util/cleanup.c4
-rw-r--r--util/cleanup.h18
-rw-r--r--util/json.c26
-rw-r--r--util/json.h17
-rw-r--r--util/log.c90
-rw-r--r--util/log.h34
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 */