]> git.ipfire.org Git - thirdparty/kmod.git/blame - libkmod/libkmod.c
Convert spaces to tabs
[thirdparty/kmod.git] / libkmod / libkmod.c
CommitLineData
ecd40ee4 1/*
586fc304
LDM
2 * libkmod - interface to kernel module operations
3 *
4 * Copyright (C) 2011 ProFUSION embedded systems
5 * Copyright (C) 2011 Lucas De Marchi <lucas.de.marchi@gmail.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation version 2.1.
10 *
11 * This library 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 GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
ecd40ee4
LDM
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <stddef.h>
24#include <stdarg.h>
25#include <unistd.h>
26#include <errno.h>
27#include <string.h>
28#include <ctype.h>
29
586fc304
LDM
30#include "libkmod.h"
31#include "libkmod-private.h"
ecd40ee4
LDM
32
33/**
586fc304
LDM
34 * SECTION:libkmod
35 * @short_description: libkmod context
ecd40ee4
LDM
36 *
37 * The context contains the default values for the library user,
38 * and is passed to all library operations.
39 */
40
41/**
586fc304 42 * kmod_ctx:
ecd40ee4
LDM
43 *
44 * Opaque object representing the library context.
45 */
586fc304 46struct kmod_ctx {
ecd40ee4 47 int refcount;
586fc304 48 void (*log_fn)(struct kmod_ctx *ctx,
e4351b05
LDM
49 int priority, const char *file, int line,
50 const char *fn, const char *format, va_list args);
ecd40ee4
LDM
51 void *userdata;
52 int log_priority;
53};
54
586fc304 55void kmod_log(struct kmod_ctx *ctx,
e4351b05
LDM
56 int priority, const char *file, int line, const char *fn,
57 const char *format, ...)
ecd40ee4
LDM
58{
59 va_list args;
60
61 va_start(args, format);
62 ctx->log_fn(ctx, priority, file, line, fn, format, args);
63 va_end(args);
64}
65
586fc304 66static void log_stderr(struct kmod_ctx *ctx,
e4351b05
LDM
67 int priority, const char *file, int line,
68 const char *fn, const char *format, va_list args)
ecd40ee4 69{
586fc304 70 fprintf(stderr, "libkmod: %s: ", fn);
ecd40ee4
LDM
71 vfprintf(stderr, format, args);
72}
73
74/**
586fc304
LDM
75 * kmod_get_userdata:
76 * @ctx: kmod library context
ecd40ee4
LDM
77 *
78 * Retrieve stored data pointer from library context. This might be useful
79 * to access from callbacks like a custom logging function.
80 *
81 * Returns: stored userdata
82 **/
586fc304 83KMOD_EXPORT void *kmod_get_userdata(struct kmod_ctx *ctx)
ecd40ee4
LDM
84{
85 if (ctx == NULL)
86 return NULL;
87 return ctx->userdata;
88}
89
90/**
586fc304
LDM
91 * kmod_set_userdata:
92 * @ctx: kmod library context
ecd40ee4
LDM
93 * @userdata: data pointer
94 *
95 * Store custom @userdata in the library context.
96 **/
586fc304 97KMOD_EXPORT void kmod_set_userdata(struct kmod_ctx *ctx, void *userdata)
ecd40ee4
LDM
98{
99 if (ctx == NULL)
100 return;
101 ctx->userdata = userdata;
102}
103
104static int log_priority(const char *priority)
105{
106 char *endptr;
107 int prio;
108
109 prio = strtol(priority, &endptr, 10);
110 if (endptr[0] == '\0' || isspace(endptr[0]))
111 return prio;
112 if (strncmp(priority, "err", 3) == 0)
113 return LOG_ERR;
114 if (strncmp(priority, "info", 4) == 0)
115 return LOG_INFO;
116 if (strncmp(priority, "debug", 5) == 0)
117 return LOG_DEBUG;
118 return 0;
119}
120
121/**
586fc304 122 * kmod_new:
ecd40ee4 123 *
586fc304 124 * Create kmod library context. This reads the kmod configuration
ecd40ee4
LDM
125 * and fills in the default values.
126 *
127 * The initial refcount is 1, and needs to be decremented to
586fc304 128 * release the resources of the kmod library context.
ecd40ee4 129 *
586fc304 130 * Returns: a new kmod library context
ecd40ee4 131 **/
586fc304 132KMOD_EXPORT int kmod_new(struct kmod_ctx **ctx)
ecd40ee4
LDM
133{
134 const char *env;
586fc304 135 struct kmod_ctx *c;
ecd40ee4 136
586fc304 137 c = calloc(1, sizeof(struct kmod_ctx));
ecd40ee4
LDM
138 if (!c)
139 return -ENOMEM;
140
141 c->refcount = 1;
142 c->log_fn = log_stderr;
143 c->log_priority = LOG_ERR;
144
145 /* environment overwrites config */
586fc304 146 env = getenv("KMOD_LOG");
ecd40ee4 147 if (env != NULL)
586fc304 148 kmod_set_log_priority(c, log_priority(env));
ecd40ee4
LDM
149
150 info(c, "ctx %p created\n", c);
151 dbg(c, "log_priority=%d\n", c->log_priority);
152 *ctx = c;
153 return 0;
154}
155
156/**
586fc304
LDM
157 * kmod_ref:
158 * @ctx: kmod library context
ecd40ee4 159 *
586fc304 160 * Take a reference of the kmod library context.
ecd40ee4 161 *
586fc304 162 * Returns: the passed kmod library context
ecd40ee4 163 **/
586fc304 164KMOD_EXPORT struct kmod_ctx *kmod_ref(struct kmod_ctx *ctx)
ecd40ee4
LDM
165{
166 if (ctx == NULL)
167 return NULL;
168 ctx->refcount++;
169 return ctx;
170}
171
172/**
586fc304
LDM
173 * kmod_unref:
174 * @ctx: kmod library context
ecd40ee4 175 *
586fc304 176 * Drop a reference of the kmod library context. If the refcount
ecd40ee4
LDM
177 * reaches zero, the resources of the context will be released.
178 *
179 **/
586fc304 180KMOD_EXPORT struct kmod_ctx *kmod_unref(struct kmod_ctx *ctx)
ecd40ee4
LDM
181{
182 if (ctx == NULL)
183 return NULL;
184 ctx->refcount--;
185 if (ctx->refcount > 0)
186 return ctx;
187 info(ctx, "context %p released\n", ctx);
188 free(ctx);
189 return NULL;
190}
191
192/**
586fc304
LDM
193 * kmod_set_log_fn:
194 * @ctx: kmod library context
ecd40ee4
LDM
195 * @log_fn: function to be called for logging messages
196 *
197 * The built-in logging writes to stderr. It can be
198 * overridden by a custom function, to plug log messages
199 * into the user's logging functionality.
200 *
201 **/
586fc304 202KMOD_EXPORT void kmod_set_log_fn(struct kmod_ctx *ctx,
e4351b05
LDM
203 void (*log_fn)(struct kmod_ctx *ctx,
204 int priority, const char *file,
205 int line, const char *fn,
206 const char *format, va_list args))
ecd40ee4
LDM
207{
208 ctx->log_fn = log_fn;
209 info(ctx, "custom logging function %p registered\n", log_fn);
210}
211
212/**
586fc304
LDM
213 * kmod_get_log_priority:
214 * @ctx: kmod library context
ecd40ee4
LDM
215 *
216 * Returns: the current logging priority
217 **/
586fc304 218KMOD_EXPORT int kmod_get_log_priority(struct kmod_ctx *ctx)
ecd40ee4
LDM
219{
220 return ctx->log_priority;
221}
222
223/**
586fc304
LDM
224 * kmod_set_log_priority:
225 * @ctx: kmod library context
ecd40ee4
LDM
226 * @priority: the new logging priority
227 *
228 * Set the current logging priority. The value controls which messages
229 * are logged.
230 **/
586fc304 231KMOD_EXPORT void kmod_set_log_priority(struct kmod_ctx *ctx, int priority)
ecd40ee4
LDM
232{
233 ctx->log_priority = priority;
234}
235
586fc304
LDM
236struct kmod_list_entry;
237struct kmod_list_entry *kmod_list_entry_get_next(struct kmod_list_entry *list_entry);
238const char *kmod_list_entry_get_name(struct kmod_list_entry *list_entry);
239const char *kmod_list_entry_get_value(struct kmod_list_entry *list_entry);
ecd40ee4 240
586fc304
LDM
241struct kmod_thing {
242 struct kmod_ctx *ctx;
ecd40ee4
LDM
243 int refcount;
244};
245
586fc304 246KMOD_EXPORT struct kmod_thing *kmod_thing_ref(struct kmod_thing *thing)
ecd40ee4
LDM
247{
248 if (!thing)
249 return NULL;
250 thing->refcount++;
251 return thing;
252}
253
586fc304 254KMOD_EXPORT struct kmod_thing *kmod_thing_unref(struct kmod_thing *thing)
ecd40ee4
LDM
255{
256 if (thing == NULL)
257 return NULL;
258 thing->refcount--;
259 if (thing->refcount > 0)
260 return thing;
261 dbg(thing->ctx, "context %p released\n", thing);
262 free(thing);
263 return NULL;
264}
265
586fc304 266KMOD_EXPORT struct kmod_ctx *kmod_thing_get_ctx(struct kmod_thing *thing)
ecd40ee4
LDM
267{
268 return thing->ctx;
269}
270
586fc304 271KMOD_EXPORT int kmod_thing_new_from_string(struct kmod_ctx *ctx, const char *string, struct kmod_thing **thing)
ecd40ee4 272{
586fc304 273 struct kmod_thing *t;
ecd40ee4 274
586fc304 275 t = calloc(1, sizeof(struct kmod_thing));
ecd40ee4
LDM
276 if (!t)
277 return -ENOMEM;
278
279 t->refcount = 1;
280 t->ctx = ctx;
281 *thing = t;
282 return 0;
283}
284
586fc304 285KMOD_EXPORT struct kmod_list_entry *kmod_thing_get_some_list_entry(struct kmod_thing *thing)
ecd40ee4
LDM
286{
287 return NULL;
288}