2 * libkmod - interface to kernel module operations
4 * Copyright (C) 2011-2013 ProFUSION embedded systems
5 * Copyright (C) 2013 Intel Corporation. All rights reserved.
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; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
31 #include <sys/types.h>
33 #include <shared/util.h>
36 #include "libkmod-internal.h"
61 const char *kmod_blacklist_get_modname(const struct kmod_list
*l
)
66 const char *kmod_alias_get_name(const struct kmod_list
*l
) {
67 const struct kmod_alias
*alias
= l
->data
;
71 const char *kmod_alias_get_modname(const struct kmod_list
*l
) {
72 const struct kmod_alias
*alias
= l
->data
;
73 return alias
->modname
;
76 const char *kmod_option_get_options(const struct kmod_list
*l
) {
77 const struct kmod_options
*alias
= l
->data
;
78 return alias
->options
;
81 const char *kmod_option_get_modname(const struct kmod_list
*l
) {
82 const struct kmod_options
*alias
= l
->data
;
83 return alias
->modname
;
86 const char *kmod_command_get_command(const struct kmod_list
*l
) {
87 const struct kmod_command
*alias
= l
->data
;
88 return alias
->command
;
91 const char *kmod_command_get_modname(const struct kmod_list
*l
) {
92 const struct kmod_command
*alias
= l
->data
;
93 return alias
->modname
;
96 const char *kmod_softdep_get_name(const struct kmod_list
*l
) {
97 const struct kmod_softdep
*dep
= l
->data
;
101 const char * const *kmod_softdep_get_pre(const struct kmod_list
*l
, unsigned int *count
) {
102 const struct kmod_softdep
*dep
= l
->data
;
107 const char * const *kmod_softdep_get_post(const struct kmod_list
*l
, unsigned int *count
) {
108 const struct kmod_softdep
*dep
= l
->data
;
109 *count
= dep
->n_post
;
113 static int kmod_config_add_command(struct kmod_config
*config
,
116 const char *command_name
,
117 struct kmod_list
**list
)
119 _cleanup_free_
struct kmod_command
*cmd
;
121 size_t modnamelen
= strlen(modname
) + 1;
122 size_t commandlen
= strlen(command
) + 1;
124 DBG(config
->ctx
, "modname='%s' cmd='%s %s'\n", modname
, command_name
,
127 cmd
= malloc(sizeof(*cmd
) + modnamelen
+ commandlen
);
131 cmd
->command
= sizeof(*cmd
) + modnamelen
+ (char *)cmd
;
132 memcpy(cmd
->modname
, modname
, modnamelen
);
133 memcpy(cmd
->command
, command
, commandlen
);
135 l
= kmod_list_append(*list
, cmd
);
144 static void kmod_config_free_command(struct kmod_config
*config
,
146 struct kmod_list
**list
)
148 struct kmod_command
*cmd
= l
->data
;
151 *list
= kmod_list_remove(l
);
154 static int kmod_config_add_options(struct kmod_config
*config
,
155 const char *modname
, const char *options
)
157 _cleanup_free_
struct kmod_options
*opt
;
158 struct kmod_list
*list
;
159 size_t modnamelen
= strlen(modname
) + 1;
160 size_t optionslen
= strlen(options
) + 1;
162 DBG(config
->ctx
, "modname='%s' options='%s'\n", modname
, options
);
164 opt
= malloc(sizeof(*opt
) + modnamelen
+ optionslen
);
168 opt
->options
= sizeof(*opt
) + modnamelen
+ (char *)opt
;
170 memcpy(opt
->modname
, modname
, modnamelen
);
171 memcpy(opt
->options
, options
, optionslen
);
172 strchr_replace(opt
->options
, '\t', ' ');
174 list
= kmod_list_append(config
->options
, opt
);
179 config
->options
= list
;
183 static void kmod_config_free_options(struct kmod_config
*config
,
186 struct kmod_options
*opt
= l
->data
;
190 config
->options
= kmod_list_remove(l
);
193 static int kmod_config_add_alias(struct kmod_config
*config
,
194 const char *name
, const char *modname
)
196 _cleanup_free_
struct kmod_alias
*alias
;
197 struct kmod_list
*list
;
198 size_t namelen
= strlen(name
) + 1, modnamelen
= strlen(modname
) + 1;
200 DBG(config
->ctx
, "name=%s modname=%s\n", name
, modname
);
202 alias
= malloc(sizeof(*alias
) + namelen
+ modnamelen
);
206 alias
->name
= sizeof(*alias
) + modnamelen
+ (char *)alias
;
208 memcpy(alias
->modname
, modname
, modnamelen
);
209 memcpy(alias
->name
, name
, namelen
);
211 list
= kmod_list_append(config
->aliases
, alias
);
216 config
->aliases
= list
;
220 static void kmod_config_free_alias(struct kmod_config
*config
,
223 struct kmod_alias
*alias
= l
->data
;
227 config
->aliases
= kmod_list_remove(l
);
230 static int kmod_config_add_blacklist(struct kmod_config
*config
,
233 _cleanup_free_
char *p
;
234 struct kmod_list
*list
;
236 DBG(config
->ctx
, "modname=%s\n", modname
);
242 list
= kmod_list_append(config
->blacklists
, p
);
247 config
->blacklists
= list
;
251 static void kmod_config_free_blacklist(struct kmod_config
*config
,
255 config
->blacklists
= kmod_list_remove(l
);
258 static int kmod_config_add_softdep(struct kmod_config
*config
,
262 struct kmod_list
*list
;
263 struct kmod_softdep
*dep
;
266 unsigned int n_pre
= 0, n_post
= 0;
267 size_t modnamelen
= strlen(modname
) + 1;
269 bool was_space
= false;
270 enum { S_NONE
, S_PRE
, S_POST
} mode
= S_NONE
;
272 DBG(config
->ctx
, "modname=%s\n", modname
);
274 /* analyze and count */
275 for (p
= s
= line
; ; s
++) {
295 if (plen
== sizeof("pre:") - 1 &&
296 memcmp(p
, "pre:", sizeof("pre:") - 1) == 0)
298 else if (plen
== sizeof("post:") - 1 &&
299 memcmp(p
, "post:", sizeof("post:") - 1) == 0)
301 else if (*s
!= '\0' || (*s
== '\0' && !was_space
)) {
305 } else if (mode
== S_POST
) {
315 DBG(config
->ctx
, "%u pre, %u post\n", n_pre
, n_post
);
317 dep
= malloc(sizeof(struct kmod_softdep
) + modnamelen
+
318 n_pre
* sizeof(const char *) +
319 n_post
* sizeof(const char *) +
322 ERR(config
->ctx
, "out-of-memory modname=%s\n", modname
);
326 dep
->n_post
= n_post
;
327 dep
->pre
= (const char **)((char *)dep
+ sizeof(struct kmod_softdep
));
328 dep
->post
= dep
->pre
+ n_pre
;
329 dep
->name
= (char *)(dep
->post
+ n_post
);
331 memcpy(dep
->name
, modname
, modnamelen
);
334 itr
= dep
->name
+ modnamelen
;
339 for (p
= s
= line
; ; s
++) {
359 if (plen
== sizeof("pre:") - 1 &&
360 memcmp(p
, "pre:", sizeof("pre:") - 1) == 0)
362 else if (plen
== sizeof("post:") - 1 &&
363 memcmp(p
, "post:", sizeof("post:") - 1) == 0)
365 else if (*s
!= '\0' || (*s
== '\0' && !was_space
)) {
367 dep
->pre
[n_pre
] = itr
;
368 memcpy(itr
, p
, plen
);
372 } else if (mode
== S_POST
) {
373 dep
->post
[n_post
] = itr
;
374 memcpy(itr
, p
, plen
);
385 list
= kmod_list_append(config
->softdeps
, dep
);
390 config
->softdeps
= list
;
395 static char *softdep_to_char(struct kmod_softdep
*dep
) {
396 const size_t sz_preprefix
= sizeof("pre: ") - 1;
397 const size_t sz_postprefix
= sizeof("post: ") - 1;
398 size_t sz
= 1; /* at least '\0' */
399 size_t sz_pre
, sz_post
;
400 const char *start
, *end
;
404 * Rely on the fact that dep->pre[] and dep->post[] are strv's that
405 * point to a contiguous buffer
407 if (dep
->n_pre
> 0) {
409 end
= dep
->pre
[dep
->n_pre
- 1]
410 + strlen(dep
->pre
[dep
->n_pre
- 1]);
411 sz_pre
= end
- start
;
412 sz
+= sz_pre
+ sz_preprefix
;
416 if (dep
->n_post
> 0) {
417 start
= dep
->post
[0];
418 end
= dep
->post
[dep
->n_post
- 1]
419 + strlen(dep
->post
[dep
->n_post
- 1]);
420 sz_post
= end
- start
;
421 sz
+= sz_post
+ sz_postprefix
;
425 itr
= s
= malloc(sz
);
432 memcpy(itr
, "pre: ", sz_preprefix
);
435 /* include last '\0' */
436 memcpy(itr
, dep
->pre
[0], sz_pre
+ 1);
437 for (p
= itr
; p
< itr
+ sz_pre
; p
++) {
447 memcpy(itr
, "post: ", sz_postprefix
);
448 itr
+= sz_postprefix
;
450 /* include last '\0' */
451 memcpy(itr
, dep
->post
[0], sz_post
+ 1);
452 for (p
= itr
; p
< itr
+ sz_post
; p
++) {
464 static void kmod_config_free_softdep(struct kmod_config
*config
,
468 config
->softdeps
= kmod_list_remove(l
);
471 static void kcmdline_parse_result(struct kmod_config
*config
, char *modname
,
472 char *param
, char *value
)
474 if (modname
== NULL
|| param
== NULL
)
477 DBG(config
->ctx
, "%s %s\n", modname
, param
);
479 if (streq(modname
, "modprobe") && !strncmp(param
, "blacklist=", 10)) {
481 char *t
= strsep(&value
, ",");
485 kmod_config_add_blacklist(config
, t
);
488 if (underscores(modname
) < 0) {
489 ERR(config
->ctx
, "Ignoring bad option on kernel command line while parsing module name: '%s'\n",
492 kmod_config_add_options(config
, modname
, param
);
497 static int kmod_config_parse_kcmdline(struct kmod_config
*config
)
499 char buf
[KCMD_LINE_SIZE
];
501 char *p
, *p_quote_start
, *modname
, *param
= NULL
, *value
= NULL
;
502 bool is_quoted
= false, iter
= true;
511 fd
= open("/proc/cmdline", O_RDONLY
|O_CLOEXEC
);
514 DBG(config
->ctx
, "could not open '/proc/cmdline' for reading: %m\n");
518 err
= read_str_safe(fd
, buf
, sizeof(buf
));
521 ERR(config
->ctx
, "could not read from '/proc/cmdline': %s\n",
526 state
= STATE_MODNAME
;
527 p_quote_start
= NULL
;
528 for (p
= buf
, modname
= buf
; iter
; p
++) {
531 is_quoted
= !is_quoted
;
534 * only allow starting quote as first char when looking
535 * for a modname: anything else is considered ill-formed
537 if (is_quoted
&& state
== STATE_MODNAME
&& p
== modname
) {
540 } else if (state
!= STATE_VALUE
) {
541 state
= STATE_IGNORE
;
554 if (is_quoted
&& state
== STATE_VALUE
) {
555 /* no state change*/;
556 } else if (is_quoted
) {
557 /* spaces are only allowed in the value part */
558 state
= STATE_IGNORE
;
559 } else if (state
== STATE_VALUE
|| state
== STATE_PARAM
) {
561 state
= STATE_COMPLETE
;
564 * go to next option, ignoring any possible
565 * partial match we have
568 state
= STATE_MODNAME
;
569 p_quote_start
= NULL
;
573 if (state
== STATE_MODNAME
) {
577 } else if (state
== STATE_PARAM
) {
578 state
= STATE_IGNORE
;
582 if (state
== STATE_PARAM
) {
584 * Don't set *p to '\0': the value var shadows
589 } else if (state
== STATE_MODNAME
) {
590 state
= STATE_IGNORE
;
595 if (state
== STATE_COMPLETE
) {
597 * We may need to re-quote to unmangle what the
598 * bootloader passed. Example: grub passes the option as
599 * "parport.dyndbg=file drivers/parport/ieee1284_ops.c +mpf"
601 * parport.dyndbg="file drivers/parport/ieee1284_ops.c +mpf"
603 if (p_quote_start
&& p_quote_start
< modname
) {
607 * |modname param value
610 * "parport\0dyndbg=file drivers/parport/ieee1284_ops.c +mpf" */
611 memmove(p_quote_start
, modname
, value
- modname
);
612 value
--; modname
--; param
--;
615 kcmdline_parse_result(config
, modname
, param
, value
);
616 /* start over on next iteration */
618 state
= STATE_MODNAME
;
619 p_quote_start
= NULL
;
627 * Take an fd and own it. It will be closed on return. filename is used only
630 static int kmod_config_parse(struct kmod_config
*config
, int fd
,
631 const char *filename
)
633 struct kmod_ctx
*ctx
= config
->ctx
;
636 unsigned int linenum
= 0;
639 fp
= fdopen(fd
, "r");
642 ERR(config
->ctx
, "fd %d: %m\n", fd
);
647 while ((line
= freadline_wrapped(fp
, &linenum
)) != NULL
) {
650 if (line
[0] == '\0' || line
[0] == '#')
653 cmd
= strtok_r(line
, "\t ", &saveptr
);
657 if (streq(cmd
, "alias")) {
658 char *alias
= strtok_r(NULL
, "\t ", &saveptr
);
659 char *modname
= strtok_r(NULL
, "\t ", &saveptr
);
661 if (underscores(alias
) < 0 || underscores(modname
) < 0)
664 kmod_config_add_alias(config
, alias
, modname
);
665 } else if (streq(cmd
, "blacklist")) {
666 char *modname
= strtok_r(NULL
, "\t ", &saveptr
);
668 if (underscores(modname
) < 0)
671 kmod_config_add_blacklist(config
, modname
);
672 } else if (streq(cmd
, "options")) {
673 char *modname
= strtok_r(NULL
, "\t ", &saveptr
);
674 char *options
= strtok_r(NULL
, "\0", &saveptr
);
676 if (underscores(modname
) < 0 || options
== NULL
)
679 kmod_config_add_options(config
, modname
, options
);
680 } else if (streq(cmd
, "install")) {
681 char *modname
= strtok_r(NULL
, "\t ", &saveptr
);
682 char *installcmd
= strtok_r(NULL
, "\0", &saveptr
);
684 if (underscores(modname
) < 0 || installcmd
== NULL
)
687 kmod_config_add_command(config
, modname
, installcmd
,
688 cmd
, &config
->install_commands
);
689 } else if (streq(cmd
, "remove")) {
690 char *modname
= strtok_r(NULL
, "\t ", &saveptr
);
691 char *removecmd
= strtok_r(NULL
, "\0", &saveptr
);
693 if (underscores(modname
) < 0 || removecmd
== NULL
)
696 kmod_config_add_command(config
, modname
, removecmd
,
697 cmd
, &config
->remove_commands
);
698 } else if (streq(cmd
, "softdep")) {
699 char *modname
= strtok_r(NULL
, "\t ", &saveptr
);
700 char *softdeps
= strtok_r(NULL
, "\0", &saveptr
);
702 if (underscores(modname
) < 0 || softdeps
== NULL
)
705 kmod_config_add_softdep(config
, modname
, softdeps
);
706 } else if (streq(cmd
, "include")
707 || streq(cmd
, "config")) {
708 ERR(ctx
, "%s: command %s is deprecated and not parsed anymore\n",
712 ERR(ctx
, "%s line %u: ignoring bad line starting with '%s'\n",
713 filename
, linenum
, cmd
);
725 void kmod_config_free(struct kmod_config
*config
)
727 while (config
->aliases
)
728 kmod_config_free_alias(config
, config
->aliases
);
730 while (config
->blacklists
)
731 kmod_config_free_blacklist(config
, config
->blacklists
);
733 while (config
->options
)
734 kmod_config_free_options(config
, config
->options
);
736 while (config
->install_commands
) {
737 kmod_config_free_command(config
, config
->install_commands
,
738 &config
->install_commands
);
741 while (config
->remove_commands
) {
742 kmod_config_free_command(config
, config
->remove_commands
,
743 &config
->remove_commands
);
746 while (config
->softdeps
)
747 kmod_config_free_softdep(config
, config
->softdeps
);
749 for (; config
->paths
!= NULL
;
750 config
->paths
= kmod_list_remove(config
->paths
))
751 free(config
->paths
->data
);
756 static bool conf_files_filter_out(struct kmod_ctx
*ctx
, DIR *d
,
757 const char *path
, const char *fn
)
759 size_t len
= strlen(fn
);
765 if (len
< 6 || (!streq(&fn
[len
- 5], ".conf")
766 && !streq(&fn
[len
- 6], ".alias")))
769 fstatat(dirfd(d
), fn
, &st
, 0);
771 if (S_ISDIR(st
.st_mode
)) {
772 ERR(ctx
, "Directories inside directories are not supported: "
773 "%s/%s\n", path
, fn
);
786 static int conf_files_insert_sorted(struct kmod_ctx
*ctx
,
787 struct kmod_list
**list
,
788 const char *path
, const char *name
)
790 struct kmod_list
*lpos
, *tmp
;
791 struct conf_file
*cf
;
794 bool is_single
= false;
797 name
= basename(path
);
801 kmod_list_foreach(lpos
, *list
) {
804 if ((cmp
= strcmp(name
, cf
->name
)) <= 0)
809 DBG(ctx
, "Ignoring duplicate config file: %s/%s\n", path
,
814 namelen
= strlen(name
);
815 cf
= malloc(sizeof(*cf
) + namelen
+ 1);
819 memcpy(cf
->name
, name
, namelen
+ 1);
821 cf
->is_single
= is_single
;
824 tmp
= kmod_list_append(*list
, cf
);
825 else if (lpos
== *list
)
826 tmp
= kmod_list_prepend(*list
, cf
);
828 tmp
= kmod_list_insert_before(lpos
, cf
);
835 if (lpos
== NULL
|| lpos
== *list
)
842 * Insert configuration files in @list, ignoring duplicates
844 static int conf_files_list(struct kmod_ctx
*ctx
, struct kmod_list
**list
,
846 unsigned long long *path_stamp
)
853 if (stat(path
, &st
) != 0) {
855 DBG(ctx
, "could not stat '%s': %m\n", path
);
859 *path_stamp
= stat_mstamp(&st
);
861 if (!S_ISDIR(st
.st_mode
)) {
862 conf_files_insert_sorted(ctx
, list
, path
, NULL
);
868 ERR(ctx
, "opendir(%s): %m\n", path
);
872 for (dent
= readdir(d
); dent
!= NULL
; dent
= readdir(d
)) {
873 if (conf_files_filter_out(ctx
, d
, path
, dent
->d_name
))
876 conf_files_insert_sorted(ctx
, list
, path
, dent
->d_name
);
883 int kmod_config_new(struct kmod_ctx
*ctx
, struct kmod_config
**p_config
,
884 const char * const *config_paths
)
886 struct kmod_config
*config
;
887 struct kmod_list
*list
= NULL
;
888 struct kmod_list
*path_list
= NULL
;
891 conf_files_insert_sorted(ctx
, &list
, kmod_get_dirname(ctx
), "modules.softdep");
893 for (i
= 0; config_paths
[i
] != NULL
; i
++) {
894 const char *path
= config_paths
[i
];
895 unsigned long long path_stamp
= 0;
897 struct kmod_list
*tmp
;
898 struct kmod_config_path
*cf
;
900 if (conf_files_list(ctx
, &list
, path
, &path_stamp
) < 0)
903 pathlen
= strlen(path
) + 1;
904 cf
= malloc(sizeof(*cf
) + pathlen
);
908 cf
->stamp
= path_stamp
;
909 memcpy(cf
->path
, path
, pathlen
);
911 tmp
= kmod_list_append(path_list
, cf
);
919 *p_config
= config
= calloc(1, sizeof(struct kmod_config
));
923 config
->paths
= path_list
;
926 for (; list
!= NULL
; list
= kmod_list_remove(list
)) {
928 const char *fn
= buf
;
929 struct conf_file
*cf
= list
->data
;
934 } else if (snprintf(buf
, sizeof(buf
), "%s/%s",
935 cf
->path
, cf
->name
) >= (int)sizeof(buf
)) {
936 ERR(ctx
, "Error parsing %s/%s: path too long\n",
942 fd
= open(fn
, O_RDONLY
|O_CLOEXEC
);
943 DBG(ctx
, "parsing file '%s' fd=%d\n", fn
, fd
);
946 kmod_config_parse(config
, fd
, fn
);
951 kmod_config_parse_kcmdline(config
);
956 for (; list
!= NULL
; list
= kmod_list_remove(list
))
959 for (; path_list
!= NULL
; path_list
= kmod_list_remove(path_list
))
960 free(path_list
->data
);
965 /**********************************************************************
966 * struct kmod_config_iter functions
967 **********************************************************************/
970 CONFIG_TYPE_BLACKLIST
= 0,
978 struct kmod_config_iter
{
979 enum config_type type
;
981 const struct kmod_list
*list
;
982 const struct kmod_list
*curr
;
984 const char *(*get_key
)(const struct kmod_list
*l
);
985 const char *(*get_value
)(const struct kmod_list
*l
);
988 static const char *softdep_get_plain_softdep(const struct kmod_list
*l
)
990 char *s
= softdep_to_char(l
->data
);
994 static struct kmod_config_iter
*kmod_config_iter_new(const struct kmod_ctx
* ctx
,
995 enum config_type type
)
997 struct kmod_config_iter
*iter
= calloc(1, sizeof(*iter
));
998 const struct kmod_config
*config
= kmod_get_config(ctx
);
1006 case CONFIG_TYPE_BLACKLIST
:
1007 iter
->list
= config
->blacklists
;
1008 iter
->get_key
= kmod_blacklist_get_modname
;
1010 case CONFIG_TYPE_INSTALL
:
1011 iter
->list
= config
->install_commands
;
1012 iter
->get_key
= kmod_command_get_modname
;
1013 iter
->get_value
= kmod_command_get_command
;
1015 case CONFIG_TYPE_REMOVE
:
1016 iter
->list
= config
->remove_commands
;
1017 iter
->get_key
= kmod_command_get_modname
;
1018 iter
->get_value
= kmod_command_get_command
;
1020 case CONFIG_TYPE_ALIAS
:
1021 iter
->list
= config
->aliases
;
1022 iter
->get_key
= kmod_alias_get_name
;
1023 iter
->get_value
= kmod_alias_get_modname
;
1025 case CONFIG_TYPE_OPTION
:
1026 iter
->list
= config
->options
;
1027 iter
->get_key
= kmod_option_get_modname
;
1028 iter
->get_value
= kmod_option_get_options
;
1030 case CONFIG_TYPE_SOFTDEP
:
1031 iter
->list
= config
->softdeps
;
1032 iter
->get_key
= kmod_softdep_get_name
;
1033 iter
->get_value
= softdep_get_plain_softdep
;
1034 iter
->intermediate
= true;
1042 * SECTION:libkmod-config
1043 * @short_description: retrieve current libkmod configuration
1047 * kmod_config_get_blacklists:
1048 * @ctx: kmod library context
1050 * Retrieve an iterator to deal with the blacklist maintained inside the
1051 * library. See kmod_config_iter_get_key(), kmod_config_iter_get_value() and
1052 * kmod_config_iter_next(). At least one call to kmod_config_iter_next() must
1053 * be made to initialize the iterator and check if it's valid.
1055 * Returns: a new iterator over the blacklists or NULL on failure. Free it
1056 * with kmod_config_iter_free_iter().
1058 KMOD_EXPORT
struct kmod_config_iter
*kmod_config_get_blacklists(const struct kmod_ctx
*ctx
)
1063 return kmod_config_iter_new(ctx
, CONFIG_TYPE_BLACKLIST
);
1067 * kmod_config_get_install_commands:
1068 * @ctx: kmod library context
1070 * Retrieve an iterator to deal with the install commands maintained inside the
1071 * library. See kmod_config_iter_get_key(), kmod_config_iter_get_value() and
1072 * kmod_config_iter_next(). At least one call to kmod_config_iter_next() must
1073 * be made to initialize the iterator and check if it's valid.
1075 * Returns: a new iterator over the install commands or NULL on failure. Free
1076 * it with kmod_config_iter_free_iter().
1078 KMOD_EXPORT
struct kmod_config_iter
*kmod_config_get_install_commands(const struct kmod_ctx
*ctx
)
1083 return kmod_config_iter_new(ctx
, CONFIG_TYPE_INSTALL
);
1087 * kmod_config_get_remove_commands:
1088 * @ctx: kmod library context
1090 * Retrieve an iterator to deal with the remove commands maintained inside the
1091 * library. See kmod_config_iter_get_key(), kmod_config_iter_get_value() and
1092 * kmod_config_iter_next(). At least one call to kmod_config_iter_next() must
1093 * be made to initialize the iterator and check if it's valid.
1095 * Returns: a new iterator over the remove commands or NULL on failure. Free
1096 * it with kmod_config_iter_free_iter().
1098 KMOD_EXPORT
struct kmod_config_iter
*kmod_config_get_remove_commands(const struct kmod_ctx
*ctx
)
1103 return kmod_config_iter_new(ctx
, CONFIG_TYPE_REMOVE
);
1107 * kmod_config_get_aliases:
1108 * @ctx: kmod library context
1110 * Retrieve an iterator to deal with the aliases maintained inside the
1111 * library. See kmod_config_iter_get_key(), kmod_config_iter_get_value() and
1112 * kmod_config_iter_next(). At least one call to kmod_config_iter_next() must
1113 * be made to initialize the iterator and check if it's valid.
1115 * Returns: a new iterator over the aliases or NULL on failure. Free it with
1116 * kmod_config_iter_free_iter().
1118 KMOD_EXPORT
struct kmod_config_iter
*kmod_config_get_aliases(const struct kmod_ctx
*ctx
)
1123 return kmod_config_iter_new(ctx
, CONFIG_TYPE_ALIAS
);
1127 * kmod_config_get_options:
1128 * @ctx: kmod library context
1130 * Retrieve an iterator to deal with the options maintained inside the
1131 * library. See kmod_config_iter_get_key(), kmod_config_iter_get_value() and
1132 * kmod_config_iter_next(). At least one call to kmod_config_iter_next() must
1133 * be made to initialize the iterator and check if it's valid.
1135 * Returns: a new iterator over the options or NULL on failure. Free it with
1136 * kmod_config_iter_free_iter().
1138 KMOD_EXPORT
struct kmod_config_iter
*kmod_config_get_options(const struct kmod_ctx
*ctx
)
1143 return kmod_config_iter_new(ctx
, CONFIG_TYPE_OPTION
);
1147 * kmod_config_get_softdeps:
1148 * @ctx: kmod library context
1150 * Retrieve an iterator to deal with the softdeps maintained inside the
1151 * library. See kmod_config_iter_get_key(), kmod_config_iter_get_value() and
1152 * kmod_config_iter_next(). At least one call to kmod_config_iter_next() must
1153 * be made to initialize the iterator and check if it's valid.
1155 * Returns: a new iterator over the softdeps or NULL on failure. Free it with
1156 * kmod_config_iter_free_iter().
1158 KMOD_EXPORT
struct kmod_config_iter
*kmod_config_get_softdeps(const struct kmod_ctx
*ctx
)
1163 return kmod_config_iter_new(ctx
, CONFIG_TYPE_SOFTDEP
);
1167 * kmod_config_iter_get_key:
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 key of the current configuration pointed by @iter.
1176 KMOD_EXPORT
const char *kmod_config_iter_get_key(const struct kmod_config_iter
*iter
)
1178 if (iter
== NULL
|| iter
->curr
== NULL
)
1181 return iter
->get_key(iter
->curr
);
1185 * kmod_config_iter_get_value:
1186 * @iter: iterator over a certain configuration
1188 * When using a new allocated iterator, user must perform a call to
1189 * kmod_config_iter_next() to initialize iterator's position and check if it's
1192 * Returns: the value of the current configuration pointed by @iter.
1194 KMOD_EXPORT
const char *kmod_config_iter_get_value(const struct kmod_config_iter
*iter
)
1198 if (iter
== NULL
|| iter
->curr
== NULL
)
1201 if (iter
->get_value
== NULL
)
1204 if (iter
->intermediate
) {
1205 struct kmod_config_iter
*i
= (struct kmod_config_iter
*)iter
;
1208 s
= i
->data
= (void *) iter
->get_value(iter
->curr
);
1210 s
= iter
->get_value(iter
->curr
);
1216 * kmod_config_iter_next:
1217 * @iter: iterator over a certain configuration
1219 * Make @iter point to the next item of a certain configuration. It's an
1220 * automatically recycling iterator. When it reaches the end, false is
1221 * returned; then if user wants to iterate again, it's sufficient to call this
1222 * function once more.
1224 * Returns: true if next position of @iter is valid or false if its end is
1227 KMOD_EXPORT
bool kmod_config_iter_next(struct kmod_config_iter
*iter
)
1232 if (iter
->curr
== NULL
) {
1233 iter
->curr
= iter
->list
;
1234 return iter
->curr
!= NULL
;
1237 iter
->curr
= kmod_list_next(iter
->list
, iter
->curr
);
1239 return iter
->curr
!= NULL
;
1243 * kmod_config_iter_free_iter:
1244 * @iter: iterator over a certain configuration
1246 * Free resources used by the iterator.
1248 KMOD_EXPORT
void kmod_config_iter_free_iter(struct kmod_config_iter
*iter
)