17c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi/* 27c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi * libkmod - interface to kernel module operations 37c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi * 4e6b0e49b4ea7937a98b16f23d621244ee1a3e588Lucas De Marchi * Copyright (C) 2011-2013 ProFUSION embedded systems 5342e9cea262578ca847678692b2cc73d659434fdLucas De Marchi * Copyright (C) 2013 Intel Corporation. All rights reserved. 67c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi * 77c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi * This library is free software; you can redistribute it and/or 87c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi * modify it under the terms of the GNU Lesser General Public 9cb451f35d9fe25ec1dee0628f8af23f022358f6bLucas De Marchi * License as published by the Free Software Foundation; either 10cb451f35d9fe25ec1dee0628f8af23f022358f6bLucas De Marchi * version 2.1 of the License, or (at your option) any later version. 117c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi * 127c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi * This library is distributed in the hope that it will be useful, 137c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi * but WITHOUT ANY WARRANTY; without even the implied warranty of 147c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 157c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi * Lesser General Public License for more details. 167c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi * 177c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi * You should have received a copy of the GNU Lesser General Public 18dea2dfee9b301da84dbb09cf510b8ebf2ef28fffLucas De Marchi * License along with this library; if not, see <http://www.gnu.org/licenses/>. 197c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi */ 207c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 21c2e4286bb98c6bec77575ac0c6f862e7ddf6394fLucas De Marchi#include <ctype.h> 22c2e4286bb98c6bec77575ac0c6f862e7ddf6394fLucas De Marchi#include <dirent.h> 23c2e4286bb98c6bec77575ac0c6f862e7ddf6394fLucas De Marchi#include <errno.h> 24c2e4286bb98c6bec77575ac0c6f862e7ddf6394fLucas De Marchi#include <stdarg.h> 25c2e4286bb98c6bec77575ac0c6f862e7ddf6394fLucas De Marchi#include <stddef.h> 267c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi#include <stdio.h> 277c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi#include <stdlib.h> 287c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi#include <string.h> 29c2e4286bb98c6bec77575ac0c6f862e7ddf6394fLucas De Marchi#include <unistd.h> 307c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi#include <sys/stat.h> 317c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi#include <sys/types.h> 327c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 3396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi#include <shared/util.h> 3496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 357c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi#include "libkmod.h" 3683b855a6ed7028173e231eab0a39c929a962ddf5Lucas De Marchi#include "libkmod-internal.h" 377c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 387c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchistruct kmod_alias { 397c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi char *name; 4043c29d10ff8dbe1e73bcea95b1cbb7b27547f828Gustavo Sverzut Barbieri char modname[]; 417c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi}; 427c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 43615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchistruct kmod_options { 44615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi char *options; 45615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi char modname[]; 46615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi}; 47615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi 48a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchistruct kmod_command { 49a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi char *command; 50a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi char modname[]; 51a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi}; 52a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi 531c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieristruct kmod_softdep { 541c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri char *name; 551c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri const char **pre; 561c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri const char **post; 571c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri unsigned int n_pre; 581c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri unsigned int n_post; 591c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri}; 601c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 61c1c9c446287fa979bf09deca05b8e2c75216b76eLucas De Marchiconst char *kmod_blacklist_get_modname(const struct kmod_list *l) 62c1c9c446287fa979bf09deca05b8e2c75216b76eLucas De Marchi{ 63c1c9c446287fa979bf09deca05b8e2c75216b76eLucas De Marchi return l->data; 64c1c9c446287fa979bf09deca05b8e2c75216b76eLucas De Marchi} 65c1c9c446287fa979bf09deca05b8e2c75216b76eLucas De Marchi 66b0ef19f7f5837550114c2923984d4d0f76a0756aLucas De Marchiconst char *kmod_alias_get_name(const struct kmod_list *l) { 671ce08a563e4ff4a9bcae7a1514f1159232a16f71Gustavo Sverzut Barbieri const struct kmod_alias *alias = l->data; 68b0ef19f7f5837550114c2923984d4d0f76a0756aLucas De Marchi return alias->name; 69b0ef19f7f5837550114c2923984d4d0f76a0756aLucas De Marchi} 70b0ef19f7f5837550114c2923984d4d0f76a0756aLucas De Marchi 71b0ef19f7f5837550114c2923984d4d0f76a0756aLucas De Marchiconst char *kmod_alias_get_modname(const struct kmod_list *l) { 721ce08a563e4ff4a9bcae7a1514f1159232a16f71Gustavo Sverzut Barbieri const struct kmod_alias *alias = l->data; 73b0ef19f7f5837550114c2923984d4d0f76a0756aLucas De Marchi return alias->modname; 74b0ef19f7f5837550114c2923984d4d0f76a0756aLucas De Marchi} 75b0ef19f7f5837550114c2923984d4d0f76a0756aLucas De Marchi 76bd3f5535268836aa697f84fa6946e4b0fc22df0bGustavo Sverzut Barbiericonst char *kmod_option_get_options(const struct kmod_list *l) { 77bd3f5535268836aa697f84fa6946e4b0fc22df0bGustavo Sverzut Barbieri const struct kmod_options *alias = l->data; 78bd3f5535268836aa697f84fa6946e4b0fc22df0bGustavo Sverzut Barbieri return alias->options; 79bd3f5535268836aa697f84fa6946e4b0fc22df0bGustavo Sverzut Barbieri} 80bd3f5535268836aa697f84fa6946e4b0fc22df0bGustavo Sverzut Barbieri 81bd3f5535268836aa697f84fa6946e4b0fc22df0bGustavo Sverzut Barbiericonst char *kmod_option_get_modname(const struct kmod_list *l) { 82bd3f5535268836aa697f84fa6946e4b0fc22df0bGustavo Sverzut Barbieri const struct kmod_options *alias = l->data; 83bd3f5535268836aa697f84fa6946e4b0fc22df0bGustavo Sverzut Barbieri return alias->modname; 84bd3f5535268836aa697f84fa6946e4b0fc22df0bGustavo Sverzut Barbieri} 85bd3f5535268836aa697f84fa6946e4b0fc22df0bGustavo Sverzut Barbieri 86bd3f5535268836aa697f84fa6946e4b0fc22df0bGustavo Sverzut Barbiericonst char *kmod_command_get_command(const struct kmod_list *l) { 87bd3f5535268836aa697f84fa6946e4b0fc22df0bGustavo Sverzut Barbieri const struct kmod_command *alias = l->data; 88bd3f5535268836aa697f84fa6946e4b0fc22df0bGustavo Sverzut Barbieri return alias->command; 89bd3f5535268836aa697f84fa6946e4b0fc22df0bGustavo Sverzut Barbieri} 90bd3f5535268836aa697f84fa6946e4b0fc22df0bGustavo Sverzut Barbieri 91bd3f5535268836aa697f84fa6946e4b0fc22df0bGustavo Sverzut Barbiericonst char *kmod_command_get_modname(const struct kmod_list *l) { 92bd3f5535268836aa697f84fa6946e4b0fc22df0bGustavo Sverzut Barbieri const struct kmod_command *alias = l->data; 93bd3f5535268836aa697f84fa6946e4b0fc22df0bGustavo Sverzut Barbieri return alias->modname; 94bd3f5535268836aa697f84fa6946e4b0fc22df0bGustavo Sverzut Barbieri} 95bd3f5535268836aa697f84fa6946e4b0fc22df0bGustavo Sverzut Barbieri 961c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbiericonst char *kmod_softdep_get_name(const struct kmod_list *l) { 971c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri const struct kmod_softdep *dep = l->data; 981c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri return dep->name; 991c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri} 1001c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 1011c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbiericonst char * const *kmod_softdep_get_pre(const struct kmod_list *l, unsigned int *count) { 1021c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri const struct kmod_softdep *dep = l->data; 1031c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri *count = dep->n_pre; 1041c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri return dep->pre; 1051c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri} 1061c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 1071c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbiericonst char * const *kmod_softdep_get_post(const struct kmod_list *l, unsigned int *count) { 1081c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri const struct kmod_softdep *dep = l->data; 1091c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri *count = dep->n_post; 1101c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri return dep->post; 1111c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri} 1121c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 113a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchistatic int kmod_config_add_command(struct kmod_config *config, 114a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi const char *modname, 115a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi const char *command, 116a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi const char *command_name, 117a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi struct kmod_list **list) 118a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi{ 119342e9cea262578ca847678692b2cc73d659434fdLucas De Marchi _cleanup_free_ struct kmod_command *cmd; 120a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi struct kmod_list *l; 121a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi size_t modnamelen = strlen(modname) + 1; 122a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi size_t commandlen = strlen(command) + 1; 123a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi 124e5a7f6ac79d6d5006323a2e9dfd645bef478da11Lucas De Marchi DBG(config->ctx, "modname='%s' cmd='%s %s'\n", modname, command_name, 125a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi command); 126a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi 127a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi cmd = malloc(sizeof(*cmd) + modnamelen + commandlen); 128342e9cea262578ca847678692b2cc73d659434fdLucas De Marchi if (!cmd) 129342e9cea262578ca847678692b2cc73d659434fdLucas De Marchi return -ENOMEM; 130a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi 131a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi cmd->command = sizeof(*cmd) + modnamelen + (char *)cmd; 132a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi memcpy(cmd->modname, modname, modnamelen); 133a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi memcpy(cmd->command, command, commandlen); 134a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi 135a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi l = kmod_list_append(*list, cmd); 136342e9cea262578ca847678692b2cc73d659434fdLucas De Marchi if (!l) 137342e9cea262578ca847678692b2cc73d659434fdLucas De Marchi return -ENOMEM; 138a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi 139a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi *list = l; 140342e9cea262578ca847678692b2cc73d659434fdLucas De Marchi cmd = NULL; 141a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi return 0; 142a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi} 143a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi 144a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchistatic void kmod_config_free_command(struct kmod_config *config, 145a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi struct kmod_list *l, 146a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi struct kmod_list **list) 147a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi{ 148a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi struct kmod_command *cmd = l->data; 149a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi 150a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi free(cmd); 151a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi *list = kmod_list_remove(l); 152a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi} 153a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi 154615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchistatic int kmod_config_add_options(struct kmod_config *config, 155615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi const char *modname, const char *options) 156615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi{ 157342e9cea262578ca847678692b2cc73d659434fdLucas De Marchi _cleanup_free_ struct kmod_options *opt; 158615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi struct kmod_list *list; 159615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi size_t modnamelen = strlen(modname) + 1; 160615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi size_t optionslen = strlen(options) + 1; 161615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi 16223c0d012793bf50af18357abb4d10468e586e99aLucas De Marchi DBG(config->ctx, "modname='%s' options='%s'\n", modname, options); 163615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi 164615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi opt = malloc(sizeof(*opt) + modnamelen + optionslen); 165342e9cea262578ca847678692b2cc73d659434fdLucas De Marchi if (!opt) 166342e9cea262578ca847678692b2cc73d659434fdLucas De Marchi return -ENOMEM; 167615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi 168615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi opt->options = sizeof(*opt) + modnamelen + (char *)opt; 169615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi 170615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi memcpy(opt->modname, modname, modnamelen); 171615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi memcpy(opt->options, options, optionslen); 172615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi strchr_replace(opt->options, '\t', ' '); 173615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi 174615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi list = kmod_list_append(config->options, opt); 175342e9cea262578ca847678692b2cc73d659434fdLucas De Marchi if (!list) 176342e9cea262578ca847678692b2cc73d659434fdLucas De Marchi return -ENOMEM; 177615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi 178342e9cea262578ca847678692b2cc73d659434fdLucas De Marchi opt = NULL; 179615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi config->options = list; 180615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi return 0; 181615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi} 182615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi 183c35347f15cf0ed71a0929ddb0a0d8e2de5f73de8Lucas De Marchistatic void kmod_config_free_options(struct kmod_config *config, 184c35347f15cf0ed71a0929ddb0a0d8e2de5f73de8Lucas De Marchi struct kmod_list *l) 185615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi{ 186615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi struct kmod_options *opt = l->data; 187615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi 188615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi free(opt); 189615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi 190615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi config->options = kmod_list_remove(l); 191615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi} 192615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi 193d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieristatic int kmod_config_add_alias(struct kmod_config *config, 194c35347f15cf0ed71a0929ddb0a0d8e2de5f73de8Lucas De Marchi const char *name, const char *modname) 1957c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi{ 196342e9cea262578ca847678692b2cc73d659434fdLucas De Marchi _cleanup_free_ struct kmod_alias *alias; 197d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieri struct kmod_list *list; 19843c29d10ff8dbe1e73bcea95b1cbb7b27547f828Gustavo Sverzut Barbieri size_t namelen = strlen(name) + 1, modnamelen = strlen(modname) + 1; 1997c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 200d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieri DBG(config->ctx, "name=%s modname=%s\n", name, modname); 2017c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 20243c29d10ff8dbe1e73bcea95b1cbb7b27547f828Gustavo Sverzut Barbieri alias = malloc(sizeof(*alias) + namelen + modnamelen); 203d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieri if (!alias) 204342e9cea262578ca847678692b2cc73d659434fdLucas De Marchi return -ENOMEM; 20528c175edd10eb778c706fb133a40150cf1a58054Lucas De Marchi 20643c29d10ff8dbe1e73bcea95b1cbb7b27547f828Gustavo Sverzut Barbieri alias->name = sizeof(*alias) + modnamelen + (char *)alias; 20743c29d10ff8dbe1e73bcea95b1cbb7b27547f828Gustavo Sverzut Barbieri 20843c29d10ff8dbe1e73bcea95b1cbb7b27547f828Gustavo Sverzut Barbieri memcpy(alias->modname, modname, modnamelen); 20943c29d10ff8dbe1e73bcea95b1cbb7b27547f828Gustavo Sverzut Barbieri memcpy(alias->name, name, namelen); 2107c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 211d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieri list = kmod_list_append(config->aliases, alias); 212d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieri if (!list) 213342e9cea262578ca847678692b2cc73d659434fdLucas De Marchi return -ENOMEM; 21428c175edd10eb778c706fb133a40150cf1a58054Lucas De Marchi 215342e9cea262578ca847678692b2cc73d659434fdLucas De Marchi alias = NULL; 216d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieri config->aliases = list; 217d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieri return 0; 2187c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi} 2197c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 220c35347f15cf0ed71a0929ddb0a0d8e2de5f73de8Lucas De Marchistatic void kmod_config_free_alias(struct kmod_config *config, 221c35347f15cf0ed71a0929ddb0a0d8e2de5f73de8Lucas De Marchi struct kmod_list *l) 2227c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi{ 2237c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi struct kmod_alias *alias = l->data; 2247c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 2257c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi free(alias); 2267c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 227d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieri config->aliases = kmod_list_remove(l); 2287c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi} 2297c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 230d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieristatic int kmod_config_add_blacklist(struct kmod_config *config, 231c35347f15cf0ed71a0929ddb0a0d8e2de5f73de8Lucas De Marchi const char *modname) 23281cf2060e067240ad8c4b9493e1fc1df3d12c956Lucas De Marchi{ 233342e9cea262578ca847678692b2cc73d659434fdLucas De Marchi _cleanup_free_ char *p; 234d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieri struct kmod_list *list; 23581cf2060e067240ad8c4b9493e1fc1df3d12c956Lucas De Marchi 236d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieri DBG(config->ctx, "modname=%s\n", modname); 23781cf2060e067240ad8c4b9493e1fc1df3d12c956Lucas De Marchi 23881cf2060e067240ad8c4b9493e1fc1df3d12c956Lucas De Marchi p = strdup(modname); 239d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieri if (!p) 240342e9cea262578ca847678692b2cc73d659434fdLucas De Marchi return -ENOMEM; 241d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieri 242d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieri list = kmod_list_append(config->blacklists, p); 243d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieri if (!list) 244342e9cea262578ca847678692b2cc73d659434fdLucas De Marchi return -ENOMEM; 245342e9cea262578ca847678692b2cc73d659434fdLucas De Marchi 246342e9cea262578ca847678692b2cc73d659434fdLucas De Marchi p = NULL; 247d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieri config->blacklists = list; 248d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieri return 0; 24981cf2060e067240ad8c4b9493e1fc1df3d12c956Lucas De Marchi} 25081cf2060e067240ad8c4b9493e1fc1df3d12c956Lucas De Marchi 251d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieristatic void kmod_config_free_blacklist(struct kmod_config *config, 25281cf2060e067240ad8c4b9493e1fc1df3d12c956Lucas De Marchi struct kmod_list *l) 25381cf2060e067240ad8c4b9493e1fc1df3d12c956Lucas De Marchi{ 25481cf2060e067240ad8c4b9493e1fc1df3d12c956Lucas De Marchi free(l->data); 255d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieri config->blacklists = kmod_list_remove(l); 25681cf2060e067240ad8c4b9493e1fc1df3d12c956Lucas De Marchi} 25781cf2060e067240ad8c4b9493e1fc1df3d12c956Lucas De Marchi 2581c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieristatic int kmod_config_add_softdep(struct kmod_config *config, 2591c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri const char *modname, 2601c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri const char *line) 2611c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri{ 2621c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri struct kmod_list *list; 2631c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri struct kmod_softdep *dep; 2641c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri const char *s, *p; 2651c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri char *itr; 2661c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri unsigned int n_pre = 0, n_post = 0; 2671c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri size_t modnamelen = strlen(modname) + 1; 2681c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri size_t buflen = 0; 2691c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri bool was_space = false; 2701c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri enum { S_NONE, S_PRE, S_POST } mode = S_NONE; 2711c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 2721c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri DBG(config->ctx, "modname=%s\n", modname); 2731c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 2741c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri /* analyze and count */ 2751c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri for (p = s = line; ; s++) { 2761c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri size_t plen; 2771c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 2781c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri if (*s != '\0') { 2791c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri if (!isspace(*s)) { 2801c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri was_space = false; 2811c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri continue; 2821c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri } 2831c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 2841c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri if (was_space) { 2851c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri p = s + 1; 2861c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri continue; 2871c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri } 2881c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri was_space = true; 2891c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 2901c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri if (p >= s) 2911c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri continue; 2921c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri } 2931c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri plen = s - p; 2941c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 2951c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri if (plen == sizeof("pre:") - 1 && 2961c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri memcmp(p, "pre:", sizeof("pre:") - 1) == 0) 2971c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri mode = S_PRE; 2981c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri else if (plen == sizeof("post:") - 1 && 2991c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri memcmp(p, "post:", sizeof("post:") - 1) == 0) 3001c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri mode = S_POST; 3011c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri else if (*s != '\0' || (*s == '\0' && !was_space)) { 3021c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri if (mode == S_PRE) { 3031c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri buflen += plen + 1; 3041c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri n_pre++; 3051c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri } else if (mode == S_POST) { 3061c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri buflen += plen + 1; 3071c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri n_post++; 3081c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri } 3091c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri } 3101c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri p = s + 1; 3111c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri if (*s == '\0') 3121c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri break; 3131c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri } 3141c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 3151c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri DBG(config->ctx, "%u pre, %u post\n", n_pre, n_post); 3161c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 3171c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri dep = malloc(sizeof(struct kmod_softdep) + modnamelen + 3181c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri n_pre * sizeof(const char *) + 3191c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri n_post * sizeof(const char *) + 3201c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri buflen); 3211c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri if (dep == NULL) { 3221c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri ERR(config->ctx, "out-of-memory modname=%s\n", modname); 3231c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri return -ENOMEM; 3241c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri } 3251c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri dep->n_pre = n_pre; 3261c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri dep->n_post = n_post; 3271c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri dep->pre = (const char **)((char *)dep + sizeof(struct kmod_softdep)); 3281c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri dep->post = dep->pre + n_pre; 3291c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri dep->name = (char *)(dep->post + n_post); 3301c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 3311c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri memcpy(dep->name, modname, modnamelen); 3321c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 3331c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri /* copy strings */ 3341c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri itr = dep->name + modnamelen; 3351c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri n_pre = 0; 3361c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri n_post = 0; 3371c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri mode = S_NONE; 3381c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri for (p = s = line; ; s++) { 3391c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri size_t plen; 3401c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 3411c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri if (*s != '\0') { 3421c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri if (!isspace(*s)) { 3431c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri was_space = false; 3441c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri continue; 3451c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri } 3461c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 3471c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri if (was_space) { 3481c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri p = s + 1; 3491c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri continue; 3501c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri } 3511c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri was_space = true; 3521c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 3531c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri if (p >= s) 3541c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri continue; 3551c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri } 3561c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri plen = s - p; 3571c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 3581c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri if (plen == sizeof("pre:") - 1 && 3591c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri memcmp(p, "pre:", sizeof("pre:") - 1) == 0) 3601c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri mode = S_PRE; 3611c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri else if (plen == sizeof("post:") - 1 && 3621c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri memcmp(p, "post:", sizeof("post:") - 1) == 0) 3631c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri mode = S_POST; 3641c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri else if (*s != '\0' || (*s == '\0' && !was_space)) { 3651c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri if (mode == S_PRE) { 3661c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri dep->pre[n_pre] = itr; 3671c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri memcpy(itr, p, plen); 3681c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri itr[plen] = '\0'; 3691c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri itr += plen + 1; 3701c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri n_pre++; 3711c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri } else if (mode == S_POST) { 3721c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri dep->post[n_post] = itr; 3731c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri memcpy(itr, p, plen); 3741c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri itr[plen] = '\0'; 3751c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri itr += plen + 1; 3761c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri n_post++; 3771c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri } 3781c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri } 3791c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri p = s + 1; 3801c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri if (*s == '\0') 3811c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri break; 3821c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri } 3831c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 3841c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri list = kmod_list_append(config->softdeps, dep); 3851c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri if (list == NULL) { 3861c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri free(dep); 3871c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri return -ENOMEM; 3881c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri } 3891c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri config->softdeps = list; 3901c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 3911c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri return 0; 3921c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri} 3931c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 3946b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchistatic char *softdep_to_char(struct kmod_softdep *dep) { 3956b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi const size_t sz_preprefix = sizeof("pre: ") - 1; 3966b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi const size_t sz_postprefix = sizeof("post: ") - 1; 3976b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi size_t sz = 1; /* at least '\0' */ 3986b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi size_t sz_pre, sz_post; 3996b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi const char *start, *end; 4006b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi char *s, *itr; 4016b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi 4026b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi /* 4036b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi * Rely on the fact that dep->pre[] and dep->post[] are strv's that 4046b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi * point to a contiguous buffer 4056b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi */ 4066b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi if (dep->n_pre > 0) { 4076b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi start = dep->pre[0]; 4086b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi end = dep->pre[dep->n_pre - 1] 4096b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi + strlen(dep->pre[dep->n_pre - 1]); 4106b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi sz_pre = end - start; 4116b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi sz += sz_pre + sz_preprefix; 4126b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi } else 4136b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi sz_pre = 0; 4146b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi 4156b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi if (dep->n_post > 0) { 4166b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi start = dep->post[0]; 4176b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi end = dep->post[dep->n_post - 1] 4186b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi + strlen(dep->post[dep->n_post - 1]); 4196b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi sz_post = end - start; 4206b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi sz += sz_post + sz_postprefix; 4216b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi } else 4226b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi sz_post = 0; 4236b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi 4246b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi itr = s = malloc(sz); 4256b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi if (s == NULL) 4266b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi return NULL; 4276b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi 4286b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi if (sz_pre) { 4296b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi char *p; 4306b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi 4316b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi memcpy(itr, "pre: ", sz_preprefix); 4326b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi itr += sz_preprefix; 4336b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi 4346b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi /* include last '\0' */ 4356b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi memcpy(itr, dep->pre[0], sz_pre + 1); 4366b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi for (p = itr; p < itr + sz_pre; p++) { 4376b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi if (*p == '\0') 4386b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi *p = ' '; 4396b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi } 4406b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi itr = p; 4416b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi } 4426b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi 4436b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi if (sz_post) { 4446b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi char *p; 4456b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi 4466b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi memcpy(itr, "post: ", sz_postprefix); 4476b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi itr += sz_postprefix; 4486b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi 4496b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi /* include last '\0' */ 4506b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi memcpy(itr, dep->post[0], sz_post + 1); 4516b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi for (p = itr; p < itr + sz_post; p++) { 4526b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi if (*p == '\0') 4536b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi *p = ' '; 4546b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi } 4556b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi itr = p; 4566b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi } 4576b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi 4586b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi *itr = '\0'; 4596b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi 4606b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi return s; 4616b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi} 4626b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi 4631c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieristatic void kmod_config_free_softdep(struct kmod_config *config, 4641c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri struct kmod_list *l) 4651c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri{ 4661c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri free(l->data); 4671c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri config->softdeps = kmod_list_remove(l); 4681c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri} 4691c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 4701684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchistatic void kcmdline_parse_result(struct kmod_config *config, char *modname, 4711684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi char *param, char *value) 4721684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi{ 473493dc650d687a5a3acec37ea11d0d1d073b83d5eLucas De Marchi if (modname == NULL || param == NULL) 4741684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi return; 4751684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi 4761684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi DBG(config->ctx, "%s %s\n", modname, param); 4771684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi 4781684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi if (streq(modname, "modprobe") && !strncmp(param, "blacklist=", 10)) { 4791684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi for (;;) { 4801684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi char *t = strsep(&value, ","); 4811684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi if (t == NULL) 4821684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi break; 4831684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi 4841684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi kmod_config_add_blacklist(config, t); 4851684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi } 4861684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi } else { 48752c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi if (underscores(modname) < 0) { 48852c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi ERR(config->ctx, "Ignoring bad option on kernel command line while parsing module name: '%s'\n", 48952c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi modname); 49052c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi } 49152c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi kmod_config_add_options(config, modname, param); 4921684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi } 4931684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi} 4941684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi 4951684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchistatic int kmod_config_parse_kcmdline(struct kmod_config *config) 4961684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi{ 4971684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi char buf[KCMD_LINE_SIZE]; 4981684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi int fd, err; 4998df21177fba3f556d1a3e75d2648c50dfcf09ad0Lucas De Marchi char *p, *modname, *param = NULL, *value = NULL; 5008df21177fba3f556d1a3e75d2648c50dfcf09ad0Lucas De Marchi bool is_quoted = false, is_module = true; 5011684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi 50279e5ea91e04e96bdfde63b02c6859128e9b0a8adCristian RodrÃguez fd = open("/proc/cmdline", O_RDONLY|O_CLOEXEC); 503dd1cf10fc468b64c787ace4eae93f159032580d0Lucas De Marchi if (fd < 0) { 504dd1cf10fc468b64c787ace4eae93f159032580d0Lucas De Marchi err = -errno; 505dd1cf10fc468b64c787ace4eae93f159032580d0Lucas De Marchi DBG(config->ctx, "could not open '/proc/cmdline' for reading: %m\n"); 506dd1cf10fc468b64c787ace4eae93f159032580d0Lucas De Marchi return err; 507dd1cf10fc468b64c787ace4eae93f159032580d0Lucas De Marchi } 508dd1cf10fc468b64c787ace4eae93f159032580d0Lucas De Marchi 5091684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi err = read_str_safe(fd, buf, sizeof(buf)); 5101684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi close(fd); 5111684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi if (err < 0) { 5121684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi ERR(config->ctx, "could not read from '/proc/cmdline': %s\n", 5131684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi strerror(-err)); 5141684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi return err; 5151684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi } 5161684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi 5171684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi for (p = buf, modname = buf; *p != '\0' && *p != '\n'; p++) { 518f27a2b12748b55abdbdeba6ec3976033bd257947James Minor if (*p == '"') { 519f27a2b12748b55abdbdeba6ec3976033bd257947James Minor is_quoted = !is_quoted; 52031dd40a6b8fd66127496fc0772b6dbe0a3e5b823Lucas De Marchi 52131dd40a6b8fd66127496fc0772b6dbe0a3e5b823Lucas De Marchi if (is_quoted) { 52231dd40a6b8fd66127496fc0772b6dbe0a3e5b823Lucas De Marchi /* don't consider a module until closing quotes */ 52331dd40a6b8fd66127496fc0772b6dbe0a3e5b823Lucas De Marchi is_module = false; 52431dd40a6b8fd66127496fc0772b6dbe0a3e5b823Lucas De Marchi } else if (param != NULL && value != NULL) { 52531dd40a6b8fd66127496fc0772b6dbe0a3e5b823Lucas De Marchi /* 52631dd40a6b8fd66127496fc0772b6dbe0a3e5b823Lucas De Marchi * If we are indeed expecting a value and 52731dd40a6b8fd66127496fc0772b6dbe0a3e5b823Lucas De Marchi * closing quotes, then this can be considered 52831dd40a6b8fd66127496fc0772b6dbe0a3e5b823Lucas De Marchi * a valid option for a module 52931dd40a6b8fd66127496fc0772b6dbe0a3e5b823Lucas De Marchi */ 53031dd40a6b8fd66127496fc0772b6dbe0a3e5b823Lucas De Marchi is_module = true; 53131dd40a6b8fd66127496fc0772b6dbe0a3e5b823Lucas De Marchi } 53231dd40a6b8fd66127496fc0772b6dbe0a3e5b823Lucas De Marchi 533f27a2b12748b55abdbdeba6ec3976033bd257947James Minor continue; 534f27a2b12748b55abdbdeba6ec3976033bd257947James Minor } 535f27a2b12748b55abdbdeba6ec3976033bd257947James Minor if (is_quoted) 536f27a2b12748b55abdbdeba6ec3976033bd257947James Minor continue; 53731dd40a6b8fd66127496fc0772b6dbe0a3e5b823Lucas De Marchi 5381684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi switch (*p) { 5391684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi case ' ': 5401684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi *p = '\0'; 541aa878540e6f3825cd5cc86d0771e203a6da6231aMichal Marek if (is_module) 542aa878540e6f3825cd5cc86d0771e203a6da6231aMichal Marek kcmdline_parse_result(config, modname, param, value); 5431684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi param = value = NULL; 5441684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi modname = p + 1; 5458df21177fba3f556d1a3e75d2648c50dfcf09ad0Lucas De Marchi is_module = true; 5461684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi break; 5471684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi case '.': 54866f3228d17d66d7e2dd484427259290fbc82b2f0Lucas De Marchi if (param == NULL) { 54966f3228d17d66d7e2dd484427259290fbc82b2f0Lucas De Marchi *p = '\0'; 55066f3228d17d66d7e2dd484427259290fbc82b2f0Lucas De Marchi param = p + 1; 55166f3228d17d66d7e2dd484427259290fbc82b2f0Lucas De Marchi } 5521684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi break; 5531684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi case '=': 554135bffd652cf3afbbb9b9639732cc272e74b6ef8Lucas De Marchi if (param != NULL) 555135bffd652cf3afbbb9b9639732cc272e74b6ef8Lucas De Marchi value = p + 1; 556aa878540e6f3825cd5cc86d0771e203a6da6231aMichal Marek else 5578df21177fba3f556d1a3e75d2648c50dfcf09ad0Lucas De Marchi is_module = false; 5581684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi break; 5591684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi } 5601684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi } 5611684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi 5621684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi *p = '\0'; 563aa878540e6f3825cd5cc86d0771e203a6da6231aMichal Marek if (is_module) 564aa878540e6f3825cd5cc86d0771e203a6da6231aMichal Marek kcmdline_parse_result(config, modname, param, value); 5651684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi 5661684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi return 0; 5671684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi} 5681684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi 569b7b7ac298f53db53bebbfeff9dae3e8e4f47724aLucas De Marchi/* 570b7b7ac298f53db53bebbfeff9dae3e8e4f47724aLucas De Marchi * Take an fd and own it. It will be closed on return. filename is used only 571b7b7ac298f53db53bebbfeff9dae3e8e4f47724aLucas De Marchi * for debug messages 572b7b7ac298f53db53bebbfeff9dae3e8e4f47724aLucas De Marchi */ 573b7b7ac298f53db53bebbfeff9dae3e8e4f47724aLucas De Marchistatic int kmod_config_parse(struct kmod_config *config, int fd, 574b7b7ac298f53db53bebbfeff9dae3e8e4f47724aLucas De Marchi const char *filename) 5757c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi{ 576d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieri struct kmod_ctx *ctx = config->ctx; 5777c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi char *line; 5787c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi FILE *fp; 579759214fad036866c55b70e6fa1437f19fc08f255Lucas De Marchi unsigned int linenum = 0; 580b7b7ac298f53db53bebbfeff9dae3e8e4f47724aLucas De Marchi int err; 5817c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 582b7b7ac298f53db53bebbfeff9dae3e8e4f47724aLucas De Marchi fp = fdopen(fd, "r"); 583b7b7ac298f53db53bebbfeff9dae3e8e4f47724aLucas De Marchi if (fp == NULL) { 584b7b7ac298f53db53bebbfeff9dae3e8e4f47724aLucas De Marchi err = -errno; 585050db08c57c10cb964d337c5668c4dce309b8d41Lucas De Marchi ERR(config->ctx, "fd %d: %m\n", fd); 586b7b7ac298f53db53bebbfeff9dae3e8e4f47724aLucas De Marchi close(fd); 587b7b7ac298f53db53bebbfeff9dae3e8e4f47724aLucas De Marchi return err; 588b7b7ac298f53db53bebbfeff9dae3e8e4f47724aLucas De Marchi } 5897c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 590aafd38359adfd93b1f8c1e84b8bd7bc9e1b0b6cfLucas De Marchi while ((line = freadline_wrapped(fp, &linenum)) != NULL) { 591c11e62bfd425fe4bcbb1729215bf18f16f97f768Lucas De Marchi char *cmd, *saveptr; 5927c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 5937c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi if (line[0] == '\0' || line[0] == '#') 5947c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi goto done_next; 5957c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 596c11e62bfd425fe4bcbb1729215bf18f16f97f768Lucas De Marchi cmd = strtok_r(line, "\t ", &saveptr); 5977c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi if (cmd == NULL) 5987c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi goto done_next; 5997c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 600877e80cd934951c02b437fd81c5a2609c20176beLucas De Marchi if (streq(cmd, "alias")) { 601c11e62bfd425fe4bcbb1729215bf18f16f97f768Lucas De Marchi char *alias = strtok_r(NULL, "\t ", &saveptr); 602c11e62bfd425fe4bcbb1729215bf18f16f97f768Lucas De Marchi char *modname = strtok_r(NULL, "\t ", &saveptr); 6037c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 60452c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi if (underscores(alias) < 0 || underscores(modname) < 0) 6057c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi goto syntax_error; 6067c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 60752c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi kmod_config_add_alias(config, alias, modname); 608877e80cd934951c02b437fd81c5a2609c20176beLucas De Marchi } else if (streq(cmd, "blacklist")) { 609c11e62bfd425fe4bcbb1729215bf18f16f97f768Lucas De Marchi char *modname = strtok_r(NULL, "\t ", &saveptr); 61081cf2060e067240ad8c4b9493e1fc1df3d12c956Lucas De Marchi 61152c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi if (underscores(modname) < 0) 61281cf2060e067240ad8c4b9493e1fc1df3d12c956Lucas De Marchi goto syntax_error; 61381cf2060e067240ad8c4b9493e1fc1df3d12c956Lucas De Marchi 61452c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi kmod_config_add_blacklist(config, modname); 615615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi } else if (streq(cmd, "options")) { 616615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi char *modname = strtok_r(NULL, "\t ", &saveptr); 61783121fdea6750b80011587169fa5fd943f755794Lucas De Marchi char *options = strtok_r(NULL, "\0", &saveptr); 618615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi 61952c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi if (underscores(modname) < 0 || options == NULL) 620615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi goto syntax_error; 621615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi 62252c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi kmod_config_add_options(config, modname, options); 62340ee8dadca79b97f830ba9ee04130ba0f46e390bLeandro Pereira } else if (streq(cmd, "install")) { 624a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi char *modname = strtok_r(NULL, "\t ", &saveptr); 62583121fdea6750b80011587169fa5fd943f755794Lucas De Marchi char *installcmd = strtok_r(NULL, "\0", &saveptr); 626a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi 62752c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi if (underscores(modname) < 0 || installcmd == NULL) 628a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi goto syntax_error; 629a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi 63052c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi kmod_config_add_command(config, modname, installcmd, 631a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi cmd, &config->install_commands); 63240ee8dadca79b97f830ba9ee04130ba0f46e390bLeandro Pereira } else if (streq(cmd, "remove")) { 633a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi char *modname = strtok_r(NULL, "\t ", &saveptr); 63483121fdea6750b80011587169fa5fd943f755794Lucas De Marchi char *removecmd = strtok_r(NULL, "\0", &saveptr); 635a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi 63652c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi if (underscores(modname) < 0 || removecmd == NULL) 637a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi goto syntax_error; 638a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi 63952c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi kmod_config_add_command(config, modname, removecmd, 640a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi cmd, &config->remove_commands); 64140ee8dadca79b97f830ba9ee04130ba0f46e390bLeandro Pereira } else if (streq(cmd, "softdep")) { 6421c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri char *modname = strtok_r(NULL, "\t ", &saveptr); 64383121fdea6750b80011587169fa5fd943f755794Lucas De Marchi char *softdeps = strtok_r(NULL, "\0", &saveptr); 6441c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 64552c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi if (underscores(modname) < 0 || softdeps == NULL) 6461c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri goto syntax_error; 6471c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 64852c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi kmod_config_add_softdep(config, modname, softdeps); 649615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi } else if (streq(cmd, "include") 650877e80cd934951c02b437fd81c5a2609c20176beLucas De Marchi || streq(cmd, "config")) { 6510ad5dd083750edcd56adf6f1e88445494c57dc51Lucas De Marchi ERR(ctx, "%s: command %s is deprecated and not parsed anymore\n", 65281cf2060e067240ad8c4b9493e1fc1df3d12c956Lucas De Marchi filename, cmd); 6537c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi } else { 6547c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchisyntax_error: 6557c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi ERR(ctx, "%s line %u: ignoring bad line starting with '%s'\n", 6567c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi filename, linenum, cmd); 6577c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi } 6587c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 6597c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchidone_next: 6607c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi free(line); 6617c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi } 6627c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 6637c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi fclose(fp); 6647c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 6657c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi return 0; 6667c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi} 6677c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 668d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbierivoid kmod_config_free(struct kmod_config *config) 6697c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi{ 6707c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi while (config->aliases) 671d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieri kmod_config_free_alias(config, config->aliases); 67281cf2060e067240ad8c4b9493e1fc1df3d12c956Lucas De Marchi 67381cf2060e067240ad8c4b9493e1fc1df3d12c956Lucas De Marchi while (config->blacklists) 674d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieri kmod_config_free_blacklist(config, config->blacklists); 675d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieri 676615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi while (config->options) 677615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi kmod_config_free_options(config, config->options); 678615c42be5cf756ab246ee520e3371940f1b04e02Lucas De Marchi 679a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi while (config->install_commands) { 680a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi kmod_config_free_command(config, config->install_commands, 681a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi &config->install_commands); 682a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi } 683a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi 684a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi while (config->remove_commands) { 685a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi kmod_config_free_command(config, config->remove_commands, 686a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi &config->remove_commands); 687a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi } 688a5cce6d6ef6e3b521f903f52066133ddf2ccd70bLucas De Marchi 6891c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri while (config->softdeps) 6901c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri kmod_config_free_softdep(config, config->softdeps); 6911c52260048792561160a75a2ce62217e98cd381aGustavo Sverzut Barbieri 692b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi for (; config->paths != NULL; 693b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi config->paths = kmod_list_remove(config->paths)) 694b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi free(config->paths->data); 695b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi 696d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieri free(config); 6977c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi} 6987c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 69998c80f44c96238b50678a9fc419a5b41a5598859Lucas De Marchistatic bool conf_files_filter_out(struct kmod_ctx *ctx, DIR *d, 70098c80f44c96238b50678a9fc419a5b41a5598859Lucas De Marchi const char *path, const char *fn) 7017c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi{ 7027c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi size_t len = strlen(fn); 70398c80f44c96238b50678a9fc419a5b41a5598859Lucas De Marchi struct stat st; 7047c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 7057c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi if (fn[0] == '.') 7068f767e2dfa5b391b074b51f2abbc6d3562f424a2Lucas De Marchi return true; 7077c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 708877e80cd934951c02b437fd81c5a2609c20176beLucas De Marchi if (len < 6 || (!streq(&fn[len - 5], ".conf") 7099070b117ecef9a53e5224203952fc34256697fb7Dave Reisner && !streq(&fn[len - 6], ".alias"))) 7108f767e2dfa5b391b074b51f2abbc6d3562f424a2Lucas De Marchi return true; 7117c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 71298c80f44c96238b50678a9fc419a5b41a5598859Lucas De Marchi fstatat(dirfd(d), fn, &st, 0); 71398c80f44c96238b50678a9fc419a5b41a5598859Lucas De Marchi 71498c80f44c96238b50678a9fc419a5b41a5598859Lucas De Marchi if (S_ISDIR(st.st_mode)) { 71598c80f44c96238b50678a9fc419a5b41a5598859Lucas De Marchi ERR(ctx, "Directories inside directories are not supported: " 71698c80f44c96238b50678a9fc419a5b41a5598859Lucas De Marchi "%s/%s\n", path, fn); 7178f767e2dfa5b391b074b51f2abbc6d3562f424a2Lucas De Marchi return true; 71898c80f44c96238b50678a9fc419a5b41a5598859Lucas De Marchi } 71998c80f44c96238b50678a9fc419a5b41a5598859Lucas De Marchi 7208f767e2dfa5b391b074b51f2abbc6d3562f424a2Lucas De Marchi return false; 7217c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi} 7227c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 7237fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchistruct conf_file { 7247fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi const char *path; 7257fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi bool is_single; 7267fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi char name[]; 7277fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi}; 7287fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi 7297fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchistatic int conf_files_insert_sorted(struct kmod_ctx *ctx, 7307fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi struct kmod_list **list, 7317fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi const char *path, const char *name) 7327fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi{ 7337fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi struct kmod_list *lpos, *tmp; 7347fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi struct conf_file *cf; 7357fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi size_t namelen; 7367fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi int cmp = -1; 7377fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi bool is_single = false; 7387fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi 7397fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi if (name == NULL) { 7407fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi name = basename(path); 7417fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi is_single = true; 7427fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi } 7437fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi 7447fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi kmod_list_foreach(lpos, *list) { 7457fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi cf = lpos->data; 7467fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi 7477fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi if ((cmp = strcmp(name, cf->name)) <= 0) 7487fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi break; 7497fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi } 7507fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi 7517fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi if (cmp == 0) { 7527fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi DBG(ctx, "Ignoring duplicate config file: %s/%s\n", path, 7537fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi name); 7547fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi return -EEXIST; 7557fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi } 7567fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi 7577fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi namelen = strlen(name); 7587fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi cf = malloc(sizeof(*cf) + namelen + 1); 7597fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi if (cf == NULL) 7607fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi return -ENOMEM; 7617fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi 7627fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi memcpy(cf->name, name, namelen + 1); 7637fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi cf->path = path; 7647fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi cf->is_single = is_single; 7657fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi 7667fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi if (lpos == NULL) 7677fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi tmp = kmod_list_append(*list, cf); 7687fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi else if (lpos == *list) 7697fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi tmp = kmod_list_prepend(*list, cf); 7707fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi else 7717fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi tmp = kmod_list_insert_before(lpos, cf); 7727fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi 7737fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi if (tmp == NULL) { 7747fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi free(cf); 7757fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi return -ENOMEM; 7767fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi } 7777fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi 7787fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi if (lpos == NULL || lpos == *list) 7797fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi *list = tmp; 7807fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi 7817fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi return 0; 7827fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi} 7837fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi 7844782396cc464feb84a1552379e1909a9446178ccLucas De Marchi/* 7857fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi * Insert configuration files in @list, ignoring duplicates 7864782396cc464feb84a1552379e1909a9446178ccLucas De Marchi */ 7877fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchistatic int conf_files_list(struct kmod_ctx *ctx, struct kmod_list **list, 788b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi const char *path, 789b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi unsigned long long *path_stamp) 7907c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi{ 7917c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi DIR *d; 7927c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi int err; 7937fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi struct stat st; 7947e0385c47ae7c313a59de3ea431af7b5d18807d7Lucas De Marchi struct dirent *dent; 7957c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 7967fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi if (stat(path, &st) != 0) { 7977fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi err = -errno; 7987fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi DBG(ctx, "could not stat '%s': %m\n", path); 7997fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi return err; 8007fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi } 8017fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi 8026068aaaea8e7cdc6039e6fd7a1aeab9db9d0225bLucas De Marchi *path_stamp = stat_mstamp(&st); 803b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi 804519d27de5a209e3b64453e982feb6882ffd839c8Michal Marek if (!S_ISDIR(st.st_mode)) { 8057fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi conf_files_insert_sorted(ctx, list, path, NULL); 8067fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi return 0; 8077fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi } 8081c250ec1504150e5be09f2c4a58f9282bf937f86Lucas De Marchi 8097c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi d = opendir(path); 8107c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi if (d == NULL) { 811dfa96f154529a666bee177f4ac44e0d3a9811ad5Gustavo Sverzut Barbieri ERR(ctx, "opendir(%s): %m\n", path); 8127fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi return -EINVAL; 8137c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi } 8147c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 8157e0385c47ae7c313a59de3ea431af7b5d18807d7Lucas De Marchi for (dent = readdir(d); dent != NULL; dent = readdir(d)) { 8167e0385c47ae7c313a59de3ea431af7b5d18807d7Lucas De Marchi if (conf_files_filter_out(ctx, d, path, dent->d_name)) 8177c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi continue; 8187c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 8197e0385c47ae7c313a59de3ea431af7b5d18807d7Lucas De Marchi conf_files_insert_sorted(ctx, list, path, dent->d_name); 820b7b7ac298f53db53bebbfeff9dae3e8e4f47724aLucas De Marchi } 8217c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 8227fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi closedir(d); 8237fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi return 0; 8247c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi} 8257c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 826c35347f15cf0ed71a0929ddb0a0d8e2de5f73de8Lucas De Marchiint kmod_config_new(struct kmod_ctx *ctx, struct kmod_config **p_config, 827c35347f15cf0ed71a0929ddb0a0d8e2de5f73de8Lucas De Marchi const char * const *config_paths) 8287c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi{ 829d13e606ff6b064b9939169f1408fc5bd8ab2c1caGustavo Sverzut Barbieri struct kmod_config *config; 8307fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi struct kmod_list *list = NULL; 831b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi struct kmod_list *path_list = NULL; 832b7b7ac298f53db53bebbfeff9dae3e8e4f47724aLucas De Marchi size_t i; 8337c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 8348240333b257e96e7dc2ac2522f8bb7fb2158fafcTom Gundersen conf_files_insert_sorted(ctx, &list, kmod_get_dirname(ctx), "modules.softdep"); 8358240333b257e96e7dc2ac2522f8bb7fb2158fafcTom Gundersen 836cb8d4d3e999b1213549fc41618e86bd4ac2f4814Gustavo Sverzut Barbieri for (i = 0; config_paths[i] != NULL; i++) { 837cb8d4d3e999b1213549fc41618e86bd4ac2f4814Gustavo Sverzut Barbieri const char *path = config_paths[i]; 838b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi unsigned long long path_stamp = 0; 839b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi size_t pathlen; 840b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi struct kmod_list *tmp; 841b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi struct kmod_config_path *cf; 842b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi 843b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi if (conf_files_list(ctx, &list, path, &path_stamp) < 0) 844b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi continue; 845b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi 846b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi pathlen = strlen(path) + 1; 847b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi cf = malloc(sizeof(*cf) + pathlen); 848b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi if (cf == NULL) 849b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi goto oom; 8507c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 851b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi cf->stamp = path_stamp; 852b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi memcpy(cf->path, path, pathlen); 853b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi 854b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi tmp = kmod_list_append(path_list, cf); 855b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi if (tmp == NULL) 856b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi goto oom; 857b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi path_list = tmp; 8587fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi } 859cb8d4d3e999b1213549fc41618e86bd4ac2f4814Gustavo Sverzut Barbieri 860b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi *p_config = config = calloc(1, sizeof(struct kmod_config)); 861b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi if (config == NULL) 862b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi goto oom; 863b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi 864b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi config->paths = path_list; 86529b69c0b98bdf43907206bfcdaadadcb4a1ea195Lucas De Marchi config->ctx = ctx; 866b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi 8677fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi for (; list != NULL; list = kmod_list_remove(list)) { 86853d3a99cccf08016eff0351884e7e86a658dffd6Lucas De Marchi char buf[PATH_MAX]; 86953d3a99cccf08016eff0351884e7e86a658dffd6Lucas De Marchi const char *fn = buf; 8707fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi struct conf_file *cf = list->data; 8717fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi int fd; 872cb8d4d3e999b1213549fc41618e86bd4ac2f4814Gustavo Sverzut Barbieri 87353d3a99cccf08016eff0351884e7e86a658dffd6Lucas De Marchi if (cf->is_single) { 87453d3a99cccf08016eff0351884e7e86a658dffd6Lucas De Marchi fn = cf->path; 87553d3a99cccf08016eff0351884e7e86a658dffd6Lucas De Marchi } else if (snprintf(buf, sizeof(buf), "%s/%s", 87653d3a99cccf08016eff0351884e7e86a658dffd6Lucas De Marchi cf->path, cf->name) >= (int)sizeof(buf)) { 87753d3a99cccf08016eff0351884e7e86a658dffd6Lucas De Marchi ERR(ctx, "Error parsing %s/%s: path too long\n", 87853d3a99cccf08016eff0351884e7e86a658dffd6Lucas De Marchi cf->path, cf->name); 87953d3a99cccf08016eff0351884e7e86a658dffd6Lucas De Marchi free(cf); 88053d3a99cccf08016eff0351884e7e86a658dffd6Lucas De Marchi continue; 88153d3a99cccf08016eff0351884e7e86a658dffd6Lucas De Marchi } 8827c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 8837fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi fd = open(fn, O_RDONLY|O_CLOEXEC); 8847fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi DBG(ctx, "parsing file '%s' fd=%d\n", fn, fd); 8857c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 8867fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi if (fd >= 0) 8877fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi kmod_config_parse(config, fd, fn); 8887c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 8897fe5f7abceb4a22462cf00354f4cef95e20d74c7Lucas De Marchi free(cf); 8907c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi } 8917c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi 8921684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi kmod_config_parse_kcmdline(config); 8931684e4402c1c2ede6c4faf06e6ac1bc0ff284fc8Lucas De Marchi 894b7b7ac298f53db53bebbfeff9dae3e8e4f47724aLucas De Marchi return 0; 895b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi 896b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchioom: 897b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi for (; list != NULL; list = kmod_list_remove(list)) 898b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi free(list->data); 899b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi 900b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi for (; path_list != NULL; path_list = kmod_list_remove(path_list)) 901b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi free(path_list->data); 902b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi 903b6a4dfb1b4c02a1094e022bc3553250949f73ca9Lucas De Marchi return -ENOMEM; 9047c2ab358fd1b05be52a3a1d23fe74c7d101a69f9Lucas De Marchi} 9050017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 9060017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi/********************************************************************** 9070017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi * struct kmod_config_iter functions 9080017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi **********************************************************************/ 9090017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 9100017862911984aac14794d0a84872dcb103e5a93Lucas De Marchienum config_type { 9110017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi CONFIG_TYPE_BLACKLIST = 0, 9120017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi CONFIG_TYPE_INSTALL, 9130017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi CONFIG_TYPE_REMOVE, 9140017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi CONFIG_TYPE_ALIAS, 9150017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi CONFIG_TYPE_OPTION, 9160017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi CONFIG_TYPE_SOFTDEP, 9170017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi}; 9180017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 9190017862911984aac14794d0a84872dcb103e5a93Lucas De Marchistruct kmod_config_iter { 9200017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi enum config_type type; 9216b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi bool intermediate; 9220017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi const struct kmod_list *list; 9230017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi const struct kmod_list *curr; 9246b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi void *data; 9250017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi const char *(*get_key)(const struct kmod_list *l); 9260017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi const char *(*get_value)(const struct kmod_list *l); 9270017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi}; 9280017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 9296b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchistatic const char *softdep_get_plain_softdep(const struct kmod_list *l) 9306b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi{ 9316b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi char *s = softdep_to_char(l->data); 9326b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi return s; 9336b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi} 9346b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi 9350017862911984aac14794d0a84872dcb103e5a93Lucas De Marchistatic struct kmod_config_iter *kmod_config_iter_new(const struct kmod_ctx* ctx, 9360017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi enum config_type type) 9370017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi{ 9380017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi struct kmod_config_iter *iter = calloc(1, sizeof(*iter)); 939e7fc2c868e240b280f593934278cc719e33e90f7Lucas De Marchi const struct kmod_config *config = kmod_get_config(ctx); 9400017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 9410017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi if (iter == NULL) 9420017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi return NULL; 9430017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 9440017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi iter->type = type; 9450017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 9460017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi switch (type) { 9470017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi case CONFIG_TYPE_BLACKLIST: 948e7fc2c868e240b280f593934278cc719e33e90f7Lucas De Marchi iter->list = config->blacklists; 9490017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi iter->get_key = kmod_blacklist_get_modname; 9500017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi break; 9510017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi case CONFIG_TYPE_INSTALL: 952e7fc2c868e240b280f593934278cc719e33e90f7Lucas De Marchi iter->list = config->install_commands; 9530017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi iter->get_key = kmod_command_get_modname; 9540017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi iter->get_value = kmod_command_get_command; 9550017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi break; 9560017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi case CONFIG_TYPE_REMOVE: 957e7fc2c868e240b280f593934278cc719e33e90f7Lucas De Marchi iter->list = config->remove_commands; 9580017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi iter->get_key = kmod_command_get_modname; 9590017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi iter->get_value = kmod_command_get_command; 9600017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi break; 9610017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi case CONFIG_TYPE_ALIAS: 962e7fc2c868e240b280f593934278cc719e33e90f7Lucas De Marchi iter->list = config->aliases; 9630017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi iter->get_key = kmod_alias_get_name; 9640017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi iter->get_value = kmod_alias_get_modname; 9650017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi break; 9660017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi case CONFIG_TYPE_OPTION: 967e7fc2c868e240b280f593934278cc719e33e90f7Lucas De Marchi iter->list = config->options; 9680017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi iter->get_key = kmod_option_get_modname; 9690017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi iter->get_value = kmod_option_get_options; 9700017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi break; 9710017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi case CONFIG_TYPE_SOFTDEP: 972e7fc2c868e240b280f593934278cc719e33e90f7Lucas De Marchi iter->list = config->softdeps; 9730017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi iter->get_key = kmod_softdep_get_name; 9746b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi iter->get_value = softdep_get_plain_softdep; 9756b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi iter->intermediate = true; 9760017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi break; 9770017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi } 9780017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 9790017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi return iter; 9800017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi} 9810017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 9822f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi/** 9832f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * SECTION:libkmod-config 9842f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * @short_description: retrieve current libkmod configuration 9852f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi */ 9862f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi 9872f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi/** 9882f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * kmod_config_get_blacklists: 9892f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * @ctx: kmod library context 9902f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * 9912f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * Retrieve an iterator to deal with the blacklist maintained inside the 9922f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * library. See kmod_config_iter_get_key(), kmod_config_iter_get_value() and 9932f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * kmod_config_iter_next(). At least one call to kmod_config_iter_next() must 9942f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * be made to initialize the iterator and check if it's valid. 9952f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * 996883d8c42c7af5fe1c60868dde973acf76389b759Lucas De Marchi * Returns: a new iterator over the blacklists or NULL on failure. Free it 9972f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * with kmod_config_iter_free_iter(). 9982f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi */ 9990017862911984aac14794d0a84872dcb103e5a93Lucas De MarchiKMOD_EXPORT struct kmod_config_iter *kmod_config_get_blacklists(const struct kmod_ctx *ctx) 10000017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi{ 10010017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi if (ctx == NULL) 10020017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi return NULL;; 10030017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 10040017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi return kmod_config_iter_new(ctx, CONFIG_TYPE_BLACKLIST); 10050017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi} 10060017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 10072f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi/** 10082f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * kmod_config_get_install_commands: 10092f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * @ctx: kmod library context 10102f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * 10112f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * Retrieve an iterator to deal with the install commands maintained inside the 10122f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * library. See kmod_config_iter_get_key(), kmod_config_iter_get_value() and 10132f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * kmod_config_iter_next(). At least one call to kmod_config_iter_next() must 10142f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * be made to initialize the iterator and check if it's valid. 10152f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * 1016883d8c42c7af5fe1c60868dde973acf76389b759Lucas De Marchi * Returns: a new iterator over the install commands or NULL on failure. Free 10172f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * it with kmod_config_iter_free_iter(). 10182f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi */ 10190017862911984aac14794d0a84872dcb103e5a93Lucas De MarchiKMOD_EXPORT struct kmod_config_iter *kmod_config_get_install_commands(const struct kmod_ctx *ctx) 10200017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi{ 10210017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi if (ctx == NULL) 10220017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi return NULL;; 10230017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 10240017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi return kmod_config_iter_new(ctx, CONFIG_TYPE_INSTALL); 10250017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi} 10260017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 10272f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi/** 10282f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * kmod_config_get_remove_commands: 10292f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * @ctx: kmod library context 10302f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * 10312f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * Retrieve an iterator to deal with the remove commands maintained inside the 10322f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * library. See kmod_config_iter_get_key(), kmod_config_iter_get_value() and 10332f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * kmod_config_iter_next(). At least one call to kmod_config_iter_next() must 10342f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * be made to initialize the iterator and check if it's valid. 10352f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * 1036883d8c42c7af5fe1c60868dde973acf76389b759Lucas De Marchi * Returns: a new iterator over the remove commands or NULL on failure. Free 10372f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * it with kmod_config_iter_free_iter(). 10382f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi */ 10390017862911984aac14794d0a84872dcb103e5a93Lucas De MarchiKMOD_EXPORT struct kmod_config_iter *kmod_config_get_remove_commands(const struct kmod_ctx *ctx) 10400017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi{ 10410017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi if (ctx == NULL) 10420017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi return NULL;; 10430017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 10440017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi return kmod_config_iter_new(ctx, CONFIG_TYPE_REMOVE); 10450017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi} 10460017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 10472f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi/** 10482f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * kmod_config_get_aliases: 10492f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * @ctx: kmod library context 10502f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * 10512f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * Retrieve an iterator to deal with the aliases maintained inside the 10522f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * library. See kmod_config_iter_get_key(), kmod_config_iter_get_value() and 10532f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * kmod_config_iter_next(). At least one call to kmod_config_iter_next() must 10542f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * be made to initialize the iterator and check if it's valid. 10552f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * 1056883d8c42c7af5fe1c60868dde973acf76389b759Lucas De Marchi * Returns: a new iterator over the aliases or NULL on failure. Free it with 10572f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * kmod_config_iter_free_iter(). 10582f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi */ 10590017862911984aac14794d0a84872dcb103e5a93Lucas De MarchiKMOD_EXPORT struct kmod_config_iter *kmod_config_get_aliases(const struct kmod_ctx *ctx) 10600017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi{ 10610017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi if (ctx == NULL) 10620017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi return NULL;; 10630017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 10640017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi return kmod_config_iter_new(ctx, CONFIG_TYPE_ALIAS); 10650017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi} 10660017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 10672f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi/** 10682f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * kmod_config_get_options: 10692f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * @ctx: kmod library context 10702f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * 10712f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * Retrieve an iterator to deal with the options maintained inside the 10722f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * library. See kmod_config_iter_get_key(), kmod_config_iter_get_value() and 10732f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * kmod_config_iter_next(). At least one call to kmod_config_iter_next() must 10742f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * be made to initialize the iterator and check if it's valid. 10752f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * 1076883d8c42c7af5fe1c60868dde973acf76389b759Lucas De Marchi * Returns: a new iterator over the options or NULL on failure. Free it with 10772f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * kmod_config_iter_free_iter(). 10782f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi */ 10790017862911984aac14794d0a84872dcb103e5a93Lucas De MarchiKMOD_EXPORT struct kmod_config_iter *kmod_config_get_options(const struct kmod_ctx *ctx) 10800017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi{ 10810017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi if (ctx == NULL) 10820017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi return NULL;; 10830017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 10840017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi return kmod_config_iter_new(ctx, CONFIG_TYPE_OPTION); 10850017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi} 10860017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 10872f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi/** 10882f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * kmod_config_get_softdeps: 10892f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * @ctx: kmod library context 10902f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * 10912f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * Retrieve an iterator to deal with the softdeps maintained inside the 10922f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * library. See kmod_config_iter_get_key(), kmod_config_iter_get_value() and 10932f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * kmod_config_iter_next(). At least one call to kmod_config_iter_next() must 10942f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * be made to initialize the iterator and check if it's valid. 10952f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * 1096883d8c42c7af5fe1c60868dde973acf76389b759Lucas De Marchi * Returns: a new iterator over the softdeps or NULL on failure. Free it with 10972f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * kmod_config_iter_free_iter(). 10982f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi */ 10990017862911984aac14794d0a84872dcb103e5a93Lucas De MarchiKMOD_EXPORT struct kmod_config_iter *kmod_config_get_softdeps(const struct kmod_ctx *ctx) 11000017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi{ 11010017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi if (ctx == NULL) 11020017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi return NULL;; 11030017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 11040017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi return kmod_config_iter_new(ctx, CONFIG_TYPE_SOFTDEP); 11050017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi} 11060017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 11072f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi/** 11082f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * kmod_config_iter_get_key: 11092f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * @iter: iterator over a certain configuration 11102f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * 11112f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * When using a new allocated iterator, user must perform a call to 11122f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * kmod_config_iter_next() to initialize iterator's position and check if it's 11132f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * valid. 11142f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * 11152f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * Returns: the key of the current configuration pointed by @iter. 11162f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi */ 11170017862911984aac14794d0a84872dcb103e5a93Lucas De MarchiKMOD_EXPORT const char *kmod_config_iter_get_key(const struct kmod_config_iter *iter) 11180017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi{ 11190017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi if (iter == NULL || iter->curr == NULL) 11200017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi return NULL; 11210017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 11220017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi return iter->get_key(iter->curr); 11230017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi} 11240017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 11252f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi/** 11262f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * kmod_config_iter_get_value: 11272f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * @iter: iterator over a certain configuration 11282f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * 11292f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * When using a new allocated iterator, user must perform a call to 11302f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * kmod_config_iter_next() to initialize iterator's position and check if it's 11312f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * valid. 11322f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * 11332f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * Returns: the value of the current configuration pointed by @iter. 11342f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi */ 11350017862911984aac14794d0a84872dcb103e5a93Lucas De MarchiKMOD_EXPORT const char *kmod_config_iter_get_value(const struct kmod_config_iter *iter) 11360017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi{ 11376b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi const char *s; 11386b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi 11390017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi if (iter == NULL || iter->curr == NULL) 11400017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi return NULL; 11410017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 11420017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi if (iter->get_value == NULL) 11430017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi return NULL; 11440017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 11456b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi if (iter->intermediate) { 11466b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi struct kmod_config_iter *i = (struct kmod_config_iter *)iter; 11476b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi 11486b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi free(i->data); 11496b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi s = i->data = (void *) iter->get_value(iter->curr); 11506b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi } else 11516b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi s = iter->get_value(iter->curr); 11526b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi 11536b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi return s; 11540017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi} 11550017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 11562f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi/** 11572f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * kmod_config_iter_next: 11582f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * @iter: iterator over a certain configuration 11592f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * 11602f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * Make @iter point to the next item of a certain configuration. It's an 11612f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * automatically recycling iterator. When it reaches the end, false is 11622f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * returned; then if user wants to iterate again, it's sufficient to call this 11632f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * function once more. 11642f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * 11652f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * Returns: true if next position of @iter is valid or false if its end is 11662f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * reached. 11672f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi */ 11680017862911984aac14794d0a84872dcb103e5a93Lucas De MarchiKMOD_EXPORT bool kmod_config_iter_next(struct kmod_config_iter *iter) 11690017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi{ 11700017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi if (iter == NULL) 11710017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi return false; 11720017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 11730017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi if (iter->curr == NULL) { 11740017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi iter->curr = iter->list; 11750017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi return iter->curr != NULL; 11760017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi } 11770017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 11780017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi iter->curr = kmod_list_next(iter->list, iter->curr); 11790017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 11800017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi return iter->curr != NULL; 11810017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi} 11820017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi 11832f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi/** 11842f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * kmod_config_iter_free_iter: 11852f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * @iter: iterator over a certain configuration 11862f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * 11872f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi * Free resources used by the iterator. 11882f47c7fae9be6d786eabf89ee4dc6585e779b641Lucas De Marchi */ 11890017862911984aac14794d0a84872dcb103e5a93Lucas De MarchiKMOD_EXPORT void kmod_config_iter_free_iter(struct kmod_config_iter *iter) 11900017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi{ 11916b04ef324ab2fe3fd11051bcdd63c51751ecb309Lucas De Marchi free(iter->data); 11920017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi free(iter); 11930017862911984aac14794d0a84872dcb103e5a93Lucas De Marchi} 1194