2 * libkmod - interface to kernel module operations
4 * Copyright (C) 2011-2013 ProFUSION embedded systems
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
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.
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
30 #include <sys/types.h>
34 #include "libkmod-internal.h"
59 const char *kmod_blacklist_get_modname(const struct kmod_list
*l
)
64 const char *kmod_alias_get_name(const struct kmod_list
*l
) {
65 const struct kmod_alias
*alias
= l
->data
;
69 const char *kmod_alias_get_modname(const struct kmod_list
*l
) {
70 const struct kmod_alias
*alias
= l
->data
;
71 return alias
->modname
;
74 const char *kmod_option_get_options(const struct kmod_list
*l
) {
75 const struct kmod_options
*alias
= l
->data
;
76 return alias
->options
;
79 const char *kmod_option_get_modname(const struct kmod_list
*l
) {
80 const struct kmod_options
*alias
= l
->data
;
81 return alias
->modname
;
84 const char *kmod_command_get_command(const struct kmod_list
*l
) {
85 const struct kmod_command
*alias
= l
->data
;
86 return alias
->command
;
89 const char *kmod_command_get_modname(const struct kmod_list
*l
) {
90 const struct kmod_command
*alias
= l
->data
;
91 return alias
->modname
;
94 const char *kmod_softdep_get_name(const struct kmod_list
*l
) {
95 const struct kmod_softdep
*dep
= l
->data
;
99 const char * const *kmod_softdep_get_pre(const struct kmod_list
*l
, unsigned int *count
) {
100 const struct kmod_softdep
*dep
= l
->data
;
105 const char * const *kmod_softdep_get_post(const struct kmod_list
*l
, unsigned int *count
) {
106 const struct kmod_softdep
*dep
= l
->data
;
107 *count
= dep
->n_post
;
112 * Replace dashes with underscores.
113 * Dashes inside character range patterns (e.g. [0-9]) are left unchanged.
115 static char *underscores(struct kmod_ctx
*ctx
, char *s
)
122 for (i
= 0; s
[i
]; i
++) {
129 INFO(ctx
, "Unmatched bracket in %s\n", s
);
133 i
+= strcspn(&s
[i
], "]");
135 INFO(ctx
, "Unmatched bracket in %s\n", s
);
142 static int kmod_config_add_command(struct kmod_config
*config
,
145 const char *command_name
,
146 struct kmod_list
**list
)
148 struct kmod_command
*cmd
;
150 size_t modnamelen
= strlen(modname
) + 1;
151 size_t commandlen
= strlen(command
) + 1;
153 DBG(config
->ctx
, "modname='%s' cmd='%s %s'\n", modname
, command_name
,
156 cmd
= malloc(sizeof(*cmd
) + modnamelen
+ commandlen
);
160 cmd
->command
= sizeof(*cmd
) + modnamelen
+ (char *)cmd
;
161 memcpy(cmd
->modname
, modname
, modnamelen
);
162 memcpy(cmd
->command
, command
, commandlen
);
164 l
= kmod_list_append(*list
, cmd
);
174 ERR(config
->ctx
, "out-of-memory\n");
178 static void kmod_config_free_command(struct kmod_config
*config
,
180 struct kmod_list
**list
)
182 struct kmod_command
*cmd
= l
->data
;
185 *list
= kmod_list_remove(l
);
188 static int kmod_config_add_options(struct kmod_config
*config
,
189 const char *modname
, const char *options
)
191 struct kmod_options
*opt
;
192 struct kmod_list
*list
;
193 size_t modnamelen
= strlen(modname
) + 1;
194 size_t optionslen
= strlen(options
) + 1;
196 DBG(config
->ctx
, "modname='%s' options='%s'\n", modname
, options
);
198 opt
= malloc(sizeof(*opt
) + modnamelen
+ optionslen
);
202 opt
->options
= sizeof(*opt
) + modnamelen
+ (char *)opt
;
204 memcpy(opt
->modname
, modname
, modnamelen
);
205 memcpy(opt
->options
, options
, optionslen
);
206 strchr_replace(opt
->options
, '\t', ' ');
208 list
= kmod_list_append(config
->options
, opt
);
212 config
->options
= list
;
218 ERR(config
->ctx
, "out-of-memory\n");
222 static void kmod_config_free_options(struct kmod_config
*config
,
225 struct kmod_options
*opt
= l
->data
;
229 config
->options
= kmod_list_remove(l
);
232 static int kmod_config_add_alias(struct kmod_config
*config
,
233 const char *name
, const char *modname
)
235 struct kmod_alias
*alias
;
236 struct kmod_list
*list
;
237 size_t namelen
= strlen(name
) + 1, modnamelen
= strlen(modname
) + 1;
239 DBG(config
->ctx
, "name=%s modname=%s\n", name
, modname
);
241 alias
= malloc(sizeof(*alias
) + namelen
+ modnamelen
);
245 alias
->name
= sizeof(*alias
) + modnamelen
+ (char *)alias
;
247 memcpy(alias
->modname
, modname
, modnamelen
);
248 memcpy(alias
->name
, name
, namelen
);
250 list
= kmod_list_append(config
->aliases
, alias
);
254 config
->aliases
= list
;
260 ERR(config
->ctx
, "out-of-memory name=%s modname=%s\n", name
, modname
);
264 static void kmod_config_free_alias(struct kmod_config
*config
,
267 struct kmod_alias
*alias
= l
->data
;
271 config
->aliases
= kmod_list_remove(l
);
274 static int kmod_config_add_blacklist(struct kmod_config
*config
,
278 struct kmod_list
*list
;
280 DBG(config
->ctx
, "modname=%s\n", modname
);
286 list
= kmod_list_append(config
->blacklists
, p
);
289 config
->blacklists
= list
;
295 ERR(config
->ctx
, "out-of-memory modname=%s\n", modname
);
299 static void kmod_config_free_blacklist(struct kmod_config
*config
,
303 config
->blacklists
= kmod_list_remove(l
);
306 static int kmod_config_add_softdep(struct kmod_config
*config
,
310 struct kmod_list
*list
;
311 struct kmod_softdep
*dep
;
314 unsigned int n_pre
= 0, n_post
= 0;
315 size_t modnamelen
= strlen(modname
) + 1;
317 bool was_space
= false;
318 enum { S_NONE
, S_PRE
, S_POST
} mode
= S_NONE
;
320 DBG(config
->ctx
, "modname=%s\n", modname
);
322 /* analyze and count */
323 for (p
= s
= line
; ; s
++) {
343 if (plen
== sizeof("pre:") - 1 &&
344 memcmp(p
, "pre:", sizeof("pre:") - 1) == 0)
346 else if (plen
== sizeof("post:") - 1 &&
347 memcmp(p
, "post:", sizeof("post:") - 1) == 0)
349 else if (*s
!= '\0' || (*s
== '\0' && !was_space
)) {
353 } else if (mode
== S_POST
) {
363 DBG(config
->ctx
, "%u pre, %u post\n", n_pre
, n_post
);
365 dep
= malloc(sizeof(struct kmod_softdep
) + modnamelen
+
366 n_pre
* sizeof(const char *) +
367 n_post
* sizeof(const char *) +
370 ERR(config
->ctx
, "out-of-memory modname=%s\n", modname
);
374 dep
->n_post
= n_post
;
375 dep
->pre
= (const char **)((char *)dep
+ sizeof(struct kmod_softdep
));
376 dep
->post
= dep
->pre
+ n_pre
;
377 dep
->name
= (char *)(dep
->post
+ n_post
);
379 memcpy(dep
->name
, modname
, modnamelen
);
382 itr
= dep
->name
+ modnamelen
;
386 for (p
= s
= line
; ; s
++) {
406 if (plen
== sizeof("pre:") - 1 &&
407 memcmp(p
, "pre:", sizeof("pre:") - 1) == 0)
409 else if (plen
== sizeof("post:") - 1 &&
410 memcmp(p
, "post:", sizeof("post:") - 1) == 0)
412 else if (*s
!= '\0' || (*s
== '\0' && !was_space
)) {
414 dep
->pre
[n_pre
] = itr
;
415 memcpy(itr
, p
, plen
);
419 } else if (mode
== S_POST
) {
420 dep
->post
[n_post
] = itr
;
421 memcpy(itr
, p
, plen
);
432 list
= kmod_list_append(config
->softdeps
, dep
);
437 config
->softdeps
= list
;
442 static char *softdep_to_char(struct kmod_softdep
*dep
) {
443 const size_t sz_preprefix
= sizeof("pre: ") - 1;
444 const size_t sz_postprefix
= sizeof("post: ") - 1;
445 size_t sz
= 1; /* at least '\0' */
446 size_t sz_pre
, sz_post
;
447 const char *start
, *end
;
451 * Rely on the fact that dep->pre[] and dep->post[] are strv's that
452 * point to a contiguous buffer
454 if (dep
->n_pre
> 0) {
456 end
= dep
->pre
[dep
->n_pre
- 1]
457 + strlen(dep
->pre
[dep
->n_pre
- 1]);
458 sz_pre
= end
- start
;
459 sz
+= sz_pre
+ sz_preprefix
;
463 if (dep
->n_post
> 0) {
464 start
= dep
->post
[0];
465 end
= dep
->post
[dep
->n_post
- 1]
466 + strlen(dep
->post
[dep
->n_post
- 1]);
467 sz_post
= end
- start
;
468 sz
+= sz_post
+ sz_postprefix
;
472 itr
= s
= malloc(sz
);
479 memcpy(itr
, "pre: ", sz_preprefix
);
482 /* include last '\0' */
483 memcpy(itr
, dep
->pre
[0], sz_pre
+ 1);
484 for (p
= itr
; p
< itr
+ sz_pre
; p
++) {
494 memcpy(itr
, "post: ", sz_postprefix
);
495 itr
+= sz_postprefix
;
497 /* include last '\0' */
498 memcpy(itr
, dep
->post
[0], sz_post
+ 1);
499 for (p
= itr
; p
< itr
+ sz_post
; p
++) {
511 static void kmod_config_free_softdep(struct kmod_config
*config
,
515 config
->softdeps
= kmod_list_remove(l
);
518 static void kcmdline_parse_result(struct kmod_config
*config
, char *modname
,
519 char *param
, char *value
)
521 if (modname
== NULL
|| param
== NULL
|| value
== NULL
)
524 DBG(config
->ctx
, "%s %s\n", modname
, param
);
526 if (streq(modname
, "modprobe") && !strncmp(param
, "blacklist=", 10)) {
528 char *t
= strsep(&value
, ",");
532 kmod_config_add_blacklist(config
, t
);
535 kmod_config_add_options(config
,
536 underscores(config
->ctx
, modname
), param
);
540 static int kmod_config_parse_kcmdline(struct kmod_config
*config
)
542 char buf
[KCMD_LINE_SIZE
];
544 char *p
, *modname
, *param
= NULL
, *value
= NULL
;
546 fd
= open("/proc/cmdline", O_RDONLY
|O_CLOEXEC
);
549 DBG(config
->ctx
, "could not open '/proc/cmdline' for reading: %m\n");
553 err
= read_str_safe(fd
, buf
, sizeof(buf
));
556 ERR(config
->ctx
, "could not read from '/proc/cmdline': %s\n",
561 for (p
= buf
, modname
= buf
; *p
!= '\0' && *p
!= '\n'; p
++) {
565 kcmdline_parse_result(config
, modname
, param
, value
);
566 param
= value
= NULL
;
583 kcmdline_parse_result(config
, modname
, param
, value
);
589 * Take an fd and own it. It will be closed on return. filename is used only
592 static int kmod_config_parse(struct kmod_config
*config
, int fd
,
593 const char *filename
)
595 struct kmod_ctx
*ctx
= config
->ctx
;
598 unsigned int linenum
= 0;
601 fp
= fdopen(fd
, "r");
604 ERR(config
->ctx
, "fd %d: %m\n", fd
);
609 while ((line
= getline_wrapped(fp
, &linenum
)) != NULL
) {
612 if (line
[0] == '\0' || line
[0] == '#')
615 cmd
= strtok_r(line
, "\t ", &saveptr
);
619 if (streq(cmd
, "alias")) {
620 char *alias
= strtok_r(NULL
, "\t ", &saveptr
);
621 char *modname
= strtok_r(NULL
, "\t ", &saveptr
);
623 if (alias
== NULL
|| modname
== NULL
)
626 kmod_config_add_alias(config
,
627 underscores(ctx
, alias
),
628 underscores(ctx
, modname
));
629 } else if (streq(cmd
, "blacklist")) {
630 char *modname
= strtok_r(NULL
, "\t ", &saveptr
);
635 kmod_config_add_blacklist(config
,
636 underscores(ctx
, modname
));
637 } else if (streq(cmd
, "options")) {
638 char *modname
= strtok_r(NULL
, "\t ", &saveptr
);
639 char *options
= strtok_r(NULL
, "\0", &saveptr
);
641 if (modname
== NULL
|| options
== NULL
)
644 kmod_config_add_options(config
,
645 underscores(ctx
, modname
),
647 } else if (streq(cmd
, "install")) {
648 char *modname
= strtok_r(NULL
, "\t ", &saveptr
);
649 char *installcmd
= strtok_r(NULL
, "\0", &saveptr
);
651 if (modname
== NULL
|| installcmd
== NULL
)
654 kmod_config_add_command(config
,
655 underscores(ctx
, modname
),
657 cmd
, &config
->install_commands
);
658 } else if (streq(cmd
, "remove")) {
659 char *modname
= strtok_r(NULL
, "\t ", &saveptr
);
660 char *removecmd
= strtok_r(NULL
, "\0", &saveptr
);
662 if (modname
== NULL
|| removecmd
== NULL
)
665 kmod_config_add_command(config
,
666 underscores(ctx
, modname
),
668 cmd
, &config
->remove_commands
);
669 } else if (streq(cmd
, "softdep")) {
670 char *modname
= strtok_r(NULL
, "\t ", &saveptr
);
671 char *softdeps
= strtok_r(NULL
, "\0", &saveptr
);
673 if (modname
== NULL
|| softdeps
== NULL
)
676 kmod_config_add_softdep(config
,
677 underscores(ctx
, modname
),
679 } else if (streq(cmd
, "include")
680 || streq(cmd
, "config")) {
681 ERR(ctx
, "%s: command %s is deprecated and not parsed anymore\n",
685 ERR(ctx
, "%s line %u: ignoring bad line starting with '%s'\n",
686 filename
, linenum
, cmd
);
698 void kmod_config_free(struct kmod_config
*config
)
700 while (config
->aliases
)
701 kmod_config_free_alias(config
, config
->aliases
);
703 while (config
->blacklists
)
704 kmod_config_free_blacklist(config
, config
->blacklists
);
706 while (config
->options
)
707 kmod_config_free_options(config
, config
->options
);
709 while (config
->install_commands
) {
710 kmod_config_free_command(config
, config
->install_commands
,
711 &config
->install_commands
);
714 while (config
->remove_commands
) {
715 kmod_config_free_command(config
, config
->remove_commands
,
716 &config
->remove_commands
);
719 while (config
->softdeps
)
720 kmod_config_free_softdep(config
, config
->softdeps
);
722 for (; config
->paths
!= NULL
;
723 config
->paths
= kmod_list_remove(config
->paths
))
724 free(config
->paths
->data
);
729 static bool conf_files_filter_out(struct kmod_ctx
*ctx
, DIR *d
,
730 const char *path
, const char *fn
)
732 size_t len
= strlen(fn
);
738 if (len
< 6 || (!streq(&fn
[len
- 5], ".conf")
739 && !streq(&fn
[len
- 6], ".alias")))
742 fstatat(dirfd(d
), fn
, &st
, 0);
744 if (S_ISDIR(st
.st_mode
)) {
745 ERR(ctx
, "Directories inside directories are not supported: "
746 "%s/%s\n", path
, fn
);
759 static int conf_files_insert_sorted(struct kmod_ctx
*ctx
,
760 struct kmod_list
**list
,
761 const char *path
, const char *name
)
763 struct kmod_list
*lpos
, *tmp
;
764 struct conf_file
*cf
;
767 bool is_single
= false;
770 name
= basename(path
);
774 kmod_list_foreach(lpos
, *list
) {
777 if ((cmp
= strcmp(name
, cf
->name
)) <= 0)
782 DBG(ctx
, "Ignoring duplicate config file: %s/%s\n", path
,
787 namelen
= strlen(name
);
788 cf
= malloc(sizeof(*cf
) + namelen
+ 1);
792 memcpy(cf
->name
, name
, namelen
+ 1);
794 cf
->is_single
= is_single
;
797 tmp
= kmod_list_append(*list
, cf
);
798 else if (lpos
== *list
)
799 tmp
= kmod_list_prepend(*list
, cf
);
801 tmp
= kmod_list_insert_before(lpos
, cf
);
808 if (lpos
== NULL
|| lpos
== *list
)
815 * Insert configuration files in @list, ignoring duplicates
817 static int conf_files_list(struct kmod_ctx
*ctx
, struct kmod_list
**list
,
819 unsigned long long *path_stamp
)
825 if (stat(path
, &st
) != 0) {
827 DBG(ctx
, "could not stat '%s': %m\n", path
);
831 *path_stamp
= stat_mstamp(&st
);
833 if (S_ISREG(st
.st_mode
)) {
834 conf_files_insert_sorted(ctx
, list
, path
, NULL
);
836 } else if (!S_ISDIR(st
.st_mode
)) {
837 ERR(ctx
, "unsupported file mode %s: %#x\n",
844 ERR(ctx
, "opendir(%s): %m\n", path
);
849 struct dirent ent
, *entp
;
851 err
= readdir_r(d
, &ent
, &entp
);
853 ERR(ctx
, "reading entry %s\n", strerror(-err
));
860 if (conf_files_filter_out(ctx
, d
, path
, entp
->d_name
))
863 conf_files_insert_sorted(ctx
, list
, path
, entp
->d_name
);
874 int kmod_config_new(struct kmod_ctx
*ctx
, struct kmod_config
**p_config
,
875 const char * const *config_paths
)
877 struct kmod_config
*config
;
878 struct kmod_list
*list
= NULL
;
879 struct kmod_list
*path_list
= NULL
;
882 for (i
= 0; config_paths
[i
] != NULL
; i
++) {
883 const char *path
= config_paths
[i
];
884 unsigned long long path_stamp
= 0;
886 struct kmod_list
*tmp
;
887 struct kmod_config_path
*cf
;
889 if (conf_files_list(ctx
, &list
, path
, &path_stamp
) < 0)
892 pathlen
= strlen(path
) + 1;
893 cf
= malloc(sizeof(*cf
) + pathlen
);
897 cf
->stamp
= path_stamp
;
898 memcpy(cf
->path
, path
, pathlen
);
900 tmp
= kmod_list_append(path_list
, cf
);
906 *p_config
= config
= calloc(1, sizeof(struct kmod_config
));
910 config
->paths
= path_list
;
913 for (; list
!= NULL
; list
= kmod_list_remove(list
)) {
915 struct conf_file
*cf
= list
->data
;
919 strcpy(fn
, cf
->path
);
921 snprintf(fn
, sizeof(fn
),"%s/%s", cf
->path
,
924 fd
= open(fn
, O_RDONLY
|O_CLOEXEC
);
925 DBG(ctx
, "parsing file '%s' fd=%d\n", fn
, fd
);
928 kmod_config_parse(config
, fd
, fn
);
933 kmod_config_parse_kcmdline(config
);
938 for (; list
!= NULL
; list
= kmod_list_remove(list
))
941 for (; path_list
!= NULL
; path_list
= kmod_list_remove(path_list
))
942 free(path_list
->data
);
947 /**********************************************************************
948 * struct kmod_config_iter functions
949 **********************************************************************/
952 CONFIG_TYPE_BLACKLIST
= 0,
960 struct kmod_config_iter
{
961 enum config_type type
;
963 const struct kmod_list
*list
;
964 const struct kmod_list
*curr
;
966 const char *(*get_key
)(const struct kmod_list
*l
);
967 const char *(*get_value
)(const struct kmod_list
*l
);
970 static const char *softdep_get_plain_softdep(const struct kmod_list
*l
)
972 char *s
= softdep_to_char(l
->data
);
976 static struct kmod_config_iter
*kmod_config_iter_new(const struct kmod_ctx
* ctx
,
977 enum config_type type
)
979 struct kmod_config_iter
*iter
= calloc(1, sizeof(*iter
));
980 const struct kmod_config
*config
= kmod_get_config(ctx
);
988 case CONFIG_TYPE_BLACKLIST
:
989 iter
->list
= config
->blacklists
;
990 iter
->get_key
= kmod_blacklist_get_modname
;
992 case CONFIG_TYPE_INSTALL
:
993 iter
->list
= config
->install_commands
;
994 iter
->get_key
= kmod_command_get_modname
;
995 iter
->get_value
= kmod_command_get_command
;
997 case CONFIG_TYPE_REMOVE
:
998 iter
->list
= config
->remove_commands
;
999 iter
->get_key
= kmod_command_get_modname
;
1000 iter
->get_value
= kmod_command_get_command
;
1002 case CONFIG_TYPE_ALIAS
:
1003 iter
->list
= config
->aliases
;
1004 iter
->get_key
= kmod_alias_get_name
;
1005 iter
->get_value
= kmod_alias_get_modname
;
1007 case CONFIG_TYPE_OPTION
:
1008 iter
->list
= config
->options
;
1009 iter
->get_key
= kmod_option_get_modname
;
1010 iter
->get_value
= kmod_option_get_options
;
1012 case CONFIG_TYPE_SOFTDEP
:
1013 iter
->list
= config
->softdeps
;
1014 iter
->get_key
= kmod_softdep_get_name
;
1015 iter
->get_value
= softdep_get_plain_softdep
;
1016 iter
->intermediate
= true;
1024 * SECTION:libkmod-config
1025 * @short_description: retrieve current libkmod configuration
1029 * kmod_config_get_blacklists:
1030 * @ctx: kmod library context
1032 * Retrieve an iterator to deal with the blacklist maintained inside the
1033 * library. See kmod_config_iter_get_key(), kmod_config_iter_get_value() and
1034 * kmod_config_iter_next(). At least one call to kmod_config_iter_next() must
1035 * be made to initialize the iterator and check if it's valid.
1037 * Returns: a new iterator over the blacklists or NULL on failure. Free it
1038 * with kmod_config_iter_free_iter().
1040 KMOD_EXPORT
struct kmod_config_iter
*kmod_config_get_blacklists(const struct kmod_ctx
*ctx
)
1045 return kmod_config_iter_new(ctx
, CONFIG_TYPE_BLACKLIST
);
1049 * kmod_config_get_install_commands:
1050 * @ctx: kmod library context
1052 * Retrieve an iterator to deal with the install commands maintained inside the
1053 * library. See kmod_config_iter_get_key(), kmod_config_iter_get_value() and
1054 * kmod_config_iter_next(). At least one call to kmod_config_iter_next() must
1055 * be made to initialize the iterator and check if it's valid.
1057 * Returns: a new iterator over the install commands or NULL on failure. Free
1058 * it with kmod_config_iter_free_iter().
1060 KMOD_EXPORT
struct kmod_config_iter
*kmod_config_get_install_commands(const struct kmod_ctx
*ctx
)
1065 return kmod_config_iter_new(ctx
, CONFIG_TYPE_INSTALL
);
1069 * kmod_config_get_remove_commands:
1070 * @ctx: kmod library context
1072 * Retrieve an iterator to deal with the remove commands maintained inside the
1073 * library. See kmod_config_iter_get_key(), kmod_config_iter_get_value() and
1074 * kmod_config_iter_next(). At least one call to kmod_config_iter_next() must
1075 * be made to initialize the iterator and check if it's valid.
1077 * Returns: a new iterator over the remove commands or NULL on failure. Free
1078 * it with kmod_config_iter_free_iter().
1080 KMOD_EXPORT
struct kmod_config_iter
*kmod_config_get_remove_commands(const struct kmod_ctx
*ctx
)
1085 return kmod_config_iter_new(ctx
, CONFIG_TYPE_REMOVE
);
1089 * kmod_config_get_aliases:
1090 * @ctx: kmod library context
1092 * Retrieve an iterator to deal with the aliases maintained inside the
1093 * library. See kmod_config_iter_get_key(), kmod_config_iter_get_value() and
1094 * kmod_config_iter_next(). At least one call to kmod_config_iter_next() must
1095 * be made to initialize the iterator and check if it's valid.
1097 * Returns: a new iterator over the aliases or NULL on failure. Free it with
1098 * kmod_config_iter_free_iter().
1100 KMOD_EXPORT
struct kmod_config_iter
*kmod_config_get_aliases(const struct kmod_ctx
*ctx
)
1105 return kmod_config_iter_new(ctx
, CONFIG_TYPE_ALIAS
);
1109 * kmod_config_get_options:
1110 * @ctx: kmod library context
1112 * Retrieve an iterator to deal with the options maintained inside the
1113 * library. See kmod_config_iter_get_key(), kmod_config_iter_get_value() and
1114 * kmod_config_iter_next(). At least one call to kmod_config_iter_next() must
1115 * be made to initialize the iterator and check if it's valid.
1117 * Returns: a new iterator over the options or NULL on failure. Free it with
1118 * kmod_config_iter_free_iter().
1120 KMOD_EXPORT
struct kmod_config_iter
*kmod_config_get_options(const struct kmod_ctx
*ctx
)
1125 return kmod_config_iter_new(ctx
, CONFIG_TYPE_OPTION
);
1129 * kmod_config_get_softdeps:
1130 * @ctx: kmod library context
1132 * Retrieve an iterator to deal with the softdeps maintained inside the
1133 * library. See kmod_config_iter_get_key(), kmod_config_iter_get_value() and
1134 * kmod_config_iter_next(). At least one call to kmod_config_iter_next() must
1135 * be made to initialize the iterator and check if it's valid.
1137 * Returns: a new iterator over the softdeps or NULL on failure. Free it with
1138 * kmod_config_iter_free_iter().
1140 KMOD_EXPORT
struct kmod_config_iter
*kmod_config_get_softdeps(const struct kmod_ctx
*ctx
)
1145 return kmod_config_iter_new(ctx
, CONFIG_TYPE_SOFTDEP
);
1149 * kmod_config_iter_get_key:
1150 * @iter: iterator over a certain configuration
1152 * When using a new allocated iterator, user must perform a call to
1153 * kmod_config_iter_next() to initialize iterator's position and check if it's
1156 * Returns: the key of the current configuration pointed by @iter.
1158 KMOD_EXPORT
const char *kmod_config_iter_get_key(const struct kmod_config_iter
*iter
)
1160 if (iter
== NULL
|| iter
->curr
== NULL
)
1163 return iter
->get_key(iter
->curr
);
1167 * kmod_config_iter_get_value:
1168 * @iter: iterator over a certain configuration
1170 * When using a new allocated iterator, user must perform a call to
1171 * kmod_config_iter_next() to initialize iterator's position and check if it's
1174 * Returns: the value of the current configuration pointed by @iter.
1176 KMOD_EXPORT
const char *kmod_config_iter_get_value(const struct kmod_config_iter
*iter
)
1180 if (iter
== NULL
|| iter
->curr
== NULL
)
1183 if (iter
->get_value
== NULL
)
1186 if (iter
->intermediate
) {
1187 struct kmod_config_iter
*i
= (struct kmod_config_iter
*)iter
;
1190 s
= i
->data
= (void *) iter
->get_value(iter
->curr
);
1192 s
= iter
->get_value(iter
->curr
);
1198 * kmod_config_iter_next:
1199 * @iter: iterator over a certain configuration
1201 * Make @iter point to the next item of a certain configuration. It's an
1202 * automatically recycling iterator. When it reaches the end, false is
1203 * returned; then if user wants to iterate again, it's sufficient to call this
1204 * function once more.
1206 * Returns: true if next position of @iter is valid or false if its end is
1209 KMOD_EXPORT
bool kmod_config_iter_next(struct kmod_config_iter
*iter
)
1214 if (iter
->curr
== NULL
) {
1215 iter
->curr
= iter
->list
;
1216 return iter
->curr
!= NULL
;
1219 iter
->curr
= kmod_list_next(iter
->list
, iter
->curr
);
1221 return iter
->curr
!= NULL
;
1225 * kmod_config_iter_free_iter:
1226 * @iter: iterator over a certain configuration
1228 * Free resources used by the iterator.
1230 KMOD_EXPORT
void kmod_config_iter_free_iter(struct kmod_config_iter
*iter
)