]> git.ipfire.org Git - network.git/blob - src/libnetwork/libnetwork.c
libnetwork: Actually free context
[network.git] / src / libnetwork / libnetwork.c
1 /*#############################################################################
2 # #
3 # IPFire.org - A linux based firewall #
4 # Copyright (C) 2017 IPFire Network Development Team #
5 # #
6 # This program is free software: you can redistribute it and/or modify #
7 # it under the terms of the GNU General Public License as published by #
8 # the Free Software Foundation, either version 3 of the License, or #
9 # (at your option) any later version. #
10 # #
11 # This program is distributed in the hope that it will be useful, #
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14 # GNU General Public License for more details. #
15 # #
16 # You should have received a copy of the GNU General Public License #
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
18 # #
19 #############################################################################*/
20
21 #include <ctype.h>
22 #include <errno.h>
23 #include <stdarg.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <syslog.h>
28
29 #include <network/libnetwork.h>
30 #include <network/logging.h>
31 #include "libnetwork-private.h"
32
33 struct network_ctx {
34 int refcount;
35
36 // Logging
37 void (*log_fn)(struct network_ctx* ctx,
38 int priority, const char *file, int line, const char *fn,
39 const char *format, va_list args);
40 int log_priority;
41 };
42
43 void network_log(struct network_ctx* ctx,
44 int priority, const char* file, int line, const char* fn,
45 const char* format, ...) {
46 va_list args;
47
48 va_start(args, format);
49 ctx->log_fn(ctx, priority, file, line, fn, format, args);
50 va_end(args);
51 }
52
53 static void log_stderr(struct network_ctx* ctx,
54 int priority, const char* file, int line, const char* fn,
55 const char* format, va_list args) {
56 fprintf(stderr, "libnetwork: %s: ", fn);
57 vfprintf(stderr, format, args);
58 }
59
60 static int log_priority(const char* priority) {
61 char *endptr;
62
63 int prio = strtol(priority, &endptr, 10);
64
65 if (endptr[0] == '\0' || isspace(endptr[0]))
66 return prio;
67
68 if (strncmp(priority, "err", 3) == 0)
69 return LOG_ERR;
70
71 if (strncmp(priority, "info", 4) == 0)
72 return LOG_INFO;
73
74 if (strncmp(priority, "debug", 5) == 0)
75 return LOG_DEBUG;
76
77 return 0;
78 }
79
80 NETWORK_EXPORT int network_new(struct network_ctx** ctx) {
81 struct network_ctx* c = calloc(1, sizeof(*c));
82 if (!c)
83 return -ENOMEM;
84
85 // Initialise basic variables
86 c->refcount = 1;
87
88 // Initialise logging
89 c->log_fn = log_stderr;
90 c->log_priority = LOG_ERR;
91
92 const char* env = secure_getenv("NETWORK_LOG");
93 if (env)
94 network_set_log_priority(c, log_priority(env));
95
96 INFO(c, "network ctx %p created\n", c);
97 DEBUG(c, "log_priority=%d\n", c->log_priority);
98
99 *ctx = c;
100 return 0;
101 }
102
103 NETWORK_EXPORT struct network_ctx* network_ref(struct network_ctx* ctx) {
104 if (!ctx)
105 return NULL;
106
107 ctx->refcount++;
108 return ctx;
109 }
110
111 static void network_free(struct network_ctx* ctx) {
112 DEBUG(ctx, "network ctx %p released\n", ctx);
113
114 free(ctx);
115 }
116
117 NETWORK_EXPORT struct network_ctx* network_unref(struct network_ctx* ctx) {
118 if (!ctx)
119 return NULL;
120
121 if (--ctx->refcount > 0)
122 return ctx;
123
124 network_free(ctx);
125 return NULL;
126 }
127
128 NETWORK_EXPORT void network_set_log_fn(struct network_ctx* ctx,
129 void (*log_fn)(struct network_ctx* ctx, int priority, const char* file,
130 int line, const char* fn, const char* format, va_list args)) {
131 ctx->log_fn = log_fn;
132 INFO(ctx, "custom logging function %p registered\n", log_fn);
133 }
134
135 NETWORK_EXPORT int network_get_log_priority(struct network_ctx* ctx) {
136 return ctx->log_priority;
137 }
138
139 NETWORK_EXPORT void network_set_log_priority(struct network_ctx* ctx, int priority) {
140 ctx->log_priority = priority;
141 }
142
143 NETWORK_EXPORT const char* network_version() {
144 return "network " VERSION;
145 }