modinfo.c revision b014c490cb7dc1dd064393537c69ed5fd7b81ccf
10cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri/*
20cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri * kmod-modinfo - query kernel module information using libkmod.
30cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri *
40cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri * Copyright (C) 2011  ProFUSION embedded systems
50cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri *
60cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri * This program is free software: you can redistribute it and/or modify
70cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri * it under the terms of the GNU General Public License as published by
80cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri * the Free Software Foundation, either version 2 of the License, or
90cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri * (at your option) any later version.
100cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri *
110cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri * This program is distributed in the hope that it will be useful,
120cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri * but WITHOUT ANY WARRANTY; without even the implied warranty of
130cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
140cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri * GNU General Public License for more details.
150cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri *
160cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri * You should have received a copy of the GNU General Public License
170cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri * along with this program.  If not, see <http://www.gnu.org/licenses/>.
180cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri */
190cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
200cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri#include <stdio.h>
210cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri#include <stdlib.h>
220cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri#include <getopt.h>
230cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri#include <errno.h>
240cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri#include <string.h>
250cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri#include <limits.h>
260cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri#include <sys/utsname.h>
270cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri#include <sys/stat.h>
280cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri#include "libkmod.h"
290cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
300cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri#define LOG(fmt, ...) fprintf(stderr, "ERROR: "fmt, ##__VA_ARGS__)
310cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
320cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic char separator = '\n';
330cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic const char *field = NULL;
340cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
350cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristruct param {
360cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	struct param *next;
370cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	const char *name;
380cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	const char *param;
390cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	const char *type;
400cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	int namelen;
410cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	int paramlen;
420cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	int typelen;
430cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri};
440cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
450cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic struct param *add_param(const char *name, int namelen, const char *param, int paramlen, const char *type, int typelen, struct param **list)
460cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri{
470cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	struct param *it;
480cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
490cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	for (it = *list; it != NULL; it = it->next) {
500cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (it->namelen == namelen &&
510cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			memcmp(it->name, name, namelen) == 0)
520cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
530cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
540cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
550cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (it == NULL) {
560cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it = malloc(sizeof(struct param));
570cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (it == NULL)
580cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			return NULL;
590cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->next = *list;
600cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		*list = it;
610cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->name = name;
620cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->namelen = namelen;
630cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->param = NULL;
640cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->type = NULL;
650cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->paramlen = 0;
660cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->typelen = 0;
670cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
680cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
690cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (param != NULL) {
700cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->param = param;
710cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->paramlen = paramlen;
720cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
730cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
740cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (type != NULL) {
750cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->type = type;
760cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->typelen = typelen;
770cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
780cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
790cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	return it;
800cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri}
810cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
82b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieristatic int process_parm(const char *key, const char *value, struct param **params)
83b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri{
84b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	const char *name, *param, *type;
85b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	int namelen, paramlen, typelen;
86b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	struct param *it;
87b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	const char *colon = strchr(value, ':');
88b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	if (colon == NULL) {
89b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		LOG("Found invalid \"%s=%s\": missing ':'\n",
90b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		    key, value);
91b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		return 0;
92b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	}
93b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
94b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	name = value;
95b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	namelen = colon - value;
96b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	if (strcmp(key, "parm") == 0) {
97b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		param = colon + 1;
98b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		paramlen = strlen(param);
99b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		type = NULL;
100b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		typelen = 0;
101b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	} else {
102b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		param = NULL;
103b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		paramlen = 0;
104b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		type = colon + 1;
105b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		typelen = strlen(type);
106b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	}
107b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
108b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	it = add_param(name, namelen, param, paramlen, type, typelen, params);
109b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	if (it == NULL) {
110b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		LOG("Out of memory!\n");
111b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		return -ENOMEM;
112b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	}
113b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
114b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	return 0;
115b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri}
116b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
117b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieristatic int modinfo_params_do(const struct kmod_list *list)
118b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri{
119b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	const struct kmod_list *l;
120b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	struct param *params = NULL;
121b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	int err = 0;
122b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
123b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	kmod_list_foreach(l, list) {
124b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		const char *key = kmod_module_info_get_key(l);
125b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		const char *value = kmod_module_info_get_value(l);
126b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		if (strcmp(key, "parm") != 0 &&
127b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		    strcmp(key, "parmtype") != 0)
128b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			continue;
129b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
130b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		err = process_parm(key, value, &params);
131b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		if (err < 0)
132b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			goto end;
133b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	}
134b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
135b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	while (params != NULL) {
136b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		struct param *p = params;
137b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		params = p->next;
138b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
139b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		if (p->param == NULL)
140b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			printf("%.*s: (%.*s)%c",
141b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       p->namelen, p->name, p->typelen, p->type,
142b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       separator);
143b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		else if (p->type != NULL)
144b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			printf("%.*s:%.*s (%.*s)%c",
145b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       p->namelen, p->name,
146b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       p->paramlen, p->param,
147b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       p->typelen, p->type,
148b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       separator);
149b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		else
150b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			printf("%.*s:%.*s%c",
151b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       p->namelen, p->name,
152b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       p->paramlen, p->param,
153b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       separator);
154b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
155b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		free(p);
156b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	}
157b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
158b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieriend:
159b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	while (params != NULL) {
160b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		void *tmp = params;
161b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		params = params->next;
162b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		free(tmp);
163b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	}
164b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
165b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	return err;
166b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri}
167b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
1680cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic int modinfo_do(struct kmod_module *mod)
1690cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri{
1700cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	struct kmod_list *l, *list = NULL;
1710cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	struct param *params = NULL;
1720cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	int err;
1730cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
1740cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (field != NULL && strcmp(field, "filename") == 0) {
1750cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		printf("%s%c", kmod_module_get_path(mod), separator);
1760cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		return 0;
1770cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	} else if (field == NULL) {
1780cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		printf("%-16s%s%c", "filename:",
1790cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		       kmod_module_get_path(mod), separator);
1800cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
1810cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
1820cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	err = kmod_module_get_info(mod, &list);
1830cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (err < 0) {
1840cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		LOG("Could not get modinfo from '%s': %s\n",
1850cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			kmod_module_get_name(mod), strerror(-err));
1860cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		return err;
1870cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
1880cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
189b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	if (field != NULL && strcmp(field, "parm") == 0) {
190b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		err = modinfo_params_do(list);
191b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		goto end;
192b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	}
193b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
1940cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	kmod_list_foreach(l, list) {
1950cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		const char *key = kmod_module_info_get_key(l);
1960cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		const char *value = kmod_module_info_get_value(l);
1970cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		int keylen;
1980cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
1990cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (field != NULL) {
2000cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			if (strcmp(field, key) != 0)
2010cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri				continue;
2020cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			/* filtered output contains no key, just value */
2030cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			printf("%s%c", value, separator);
2040cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			continue;
2050cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		}
2060cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2070cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (strcmp(key, "parm") == 0 || strcmp(key, "parmtype") == 0) {
208b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			err = process_parm(key, value, &params);
209b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			if (err < 0)
2100cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri				goto end;
2110cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			continue;
2120cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		}
2130cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2140cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (separator == '\0') {
2150cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			printf("%s=%s%c", key, value, separator);
2160cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			continue;
2170cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		}
2180cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2190cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		keylen = strlen(key);
2200cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		printf("%s:%-*s%s%c", key, 15 - keylen, "", value, separator);
2210cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
2220cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2230cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (field != NULL)
2240cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		goto end;
2250cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2260cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	while (params != NULL) {
2270cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		struct param *p = params;
2280cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		params = p->next;
2290cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2300cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (p->param == NULL)
2310cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			printf("%-16s%.*s:%.*s%c", "parm:",
2320cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       p->namelen, p->name, p->typelen, p->type,
2330cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       separator);
2340cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		else if (p->type != NULL)
235515ec7960bf22c52e9e5d27c23a5dadad785a9daGustavo Sverzut Barbieri			printf("%-16s%.*s:%.*s (%.*s)%c", "parm:",
2360cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       p->namelen, p->name,
2370cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       p->paramlen, p->param,
2380cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       p->typelen, p->type,
2390cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       separator);
2400cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		else
241515ec7960bf22c52e9e5d27c23a5dadad785a9daGustavo Sverzut Barbieri			printf("%-16s%.*s:%.*s%c",
2420cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       "parm:",
2430cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       p->namelen, p->name,
2440cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       p->paramlen, p->param,
2450cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       separator);
2460cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2470cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		free(p);
2480cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
2490cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2500cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieriend:
2510cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	while (params != NULL) {
2520cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		void *tmp = params;
2530cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		params = params->next;
2540cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		free(tmp);
2550cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
2560cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	kmod_module_info_free_list(list);
2570cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2580cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	return err;
2590cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri}
2600cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2610cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic int modinfo_path_do(struct kmod_ctx *ctx, const char *path)
2620cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri{
2630cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	struct kmod_module *mod;
2640cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	int err = kmod_module_new_from_path(ctx, path, &mod);
2650cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (err < 0) {
2660cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		LOG("Module file %s not found.\n", path);
2670cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		return err;
2680cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
2690cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	err = modinfo_do(mod);
2700cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	kmod_module_unref(mod);
2710cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	return err;
2720cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri}
2730cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2740cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic int modinfo_alias_do(struct kmod_ctx *ctx, const char *alias)
2750cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri{
2760cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	struct kmod_list *l, *list = NULL;
2770cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	int err = kmod_module_new_from_lookup(ctx, alias, &list);
2780cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (err < 0) {
2790cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		LOG("Module alias %s not found.\n", alias);
2800cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		return err;
2810cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
2820cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	kmod_list_foreach(l, list) {
2830cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		struct kmod_module *mod = kmod_module_get_module(l);
2840cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		int r = modinfo_do(mod);
2850cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		kmod_module_unref(mod);
2860cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (r < 0)
2870cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			err = r;
2880cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
2890cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	kmod_module_unref_list(list);
2900cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	return err;
2910cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri}
2920cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
293022e1f0e0dae85772fc56604d3c009c23391bc10Gustavo Sverzut Barbieristatic const char cmdopts_s[] = "adlpn0F:k:b:Vh";
2940cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic const struct option cmdopts[] = {
2950cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"author", no_argument, 0, 'a'},
2960cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"description", no_argument, 0, 'd'},
2970cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"license", no_argument, 0, 'l'},
2980cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"parameters", no_argument, 0, 'p'},
2990cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"filename", no_argument, 0, 'n'},
3000cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"null", no_argument, 0, '0'},
3010cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"field", required_argument, 0, 'F'},
3020cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"set-version", required_argument, 0, 'k'},
3030cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"basedir", required_argument, 0, 'b'},
3040cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"version", no_argument, 0, 'V'},
3050cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"help", no_argument, 0, 'h'},
3060cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{NULL, 0, 0, 0}
3070cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri};
3080cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
3090cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic void help(const char *progname)
3100cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri{
3110cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	fprintf(stderr,
3120cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"Usage:\n"
3130cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t%s [options] filename [args]\n"
3140cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"Options:\n"
3150cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-a, --author                Print only 'author'\n"
3160cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-d, --description           Print only 'description'\n"
3170cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-l, --license               Print only 'license'\n"
3180cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-p, --parameters            Print only 'parm'\n"
3190cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-n, --filename              Print only 'filename'\n"
3200cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-0, --null                  Use \\0 instead of \\n\n"
3210cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-F, --field=FIELD           Print only provided FIELD\n"
3220cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-k, --set-version=VERSION   Use VERSION instead of `uname -r`\n"
3230cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-b, --basedir=DIR           Use DIR as filesystem root for /lib/modules\n"
3240cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-V, --version               Show version\n"
3250cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-h, --help                  Show this help\n",
3260cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		progname);
3270cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri}
3280cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
3290cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieriint main(int argc, char *argv[])
3300cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri{
3310cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	struct kmod_ctx *ctx;
3320cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	char dirname_buf[PATH_MAX];
3330cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	const char *dirname = NULL;
3340cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	const char *kversion = NULL;
3350cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	const char *root = NULL;
3360cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	const char *null_config = NULL;
3370cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	int i, err;
3380cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
3390cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	for (;;) {
3400cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		int c, idx = 0;
3410cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		c = getopt_long(argc, argv, cmdopts_s, cmdopts, &idx);
3420cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (c == -1)
3430cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3440cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		switch (c) {
3450cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'a':
3460cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			field = "author";
3470cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3480cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'd':
3490cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			field = "description";
3500cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3510cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'l':
3520cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			field = "license";
3530cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3540cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'p':
3550cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			field = "parm";
3560cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3570cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'n':
3580cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			field = "filename";
3590cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3600cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case '0':
3610cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			separator = '\0';
3620cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3630cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'F':
3640cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			field = optarg;
3650cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3660cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'k':
3670cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			kversion = optarg;
3680cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3690cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'b':
3700cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			root = optarg;
3710cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3720cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'h':
3730cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			help(argv[0]);
3740cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			return EXIT_SUCCESS;
3750cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'V':
3760cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			puts(PACKAGE " version " VERSION);
3770cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			return EXIT_SUCCESS;
3780cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case '?':
3790cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			return EXIT_FAILURE;
3800cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		default:
3810cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			fprintf(stderr,
3820cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri				"Error: unexpected getopt_long() value '%c'.\n",
3830cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri				c);
3840cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			return EXIT_FAILURE;
3850cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		}
3860cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
3870cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
3880cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (optind >= argc) {
3890cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		fprintf(stderr, "Error: missing module or filename.\n");
3900cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		return EXIT_FAILURE;
3910cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
3920cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
3930cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (root != NULL || kversion != NULL) {
3940cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		struct utsname u;
3950cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (root == NULL)
3960cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			root = "";
3970cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (kversion == NULL) {
3980cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			if (uname(&u) < 0) {
3990cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri				fprintf(stderr, "Error: uname() failed: %s\n",
4000cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri					strerror(errno));
4010cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri				return EXIT_FAILURE;
4020cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			}
4030cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			kversion = u.release;
4040cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		}
4050cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		snprintf(dirname_buf, sizeof(dirname_buf), "%s/lib/modules/%s",
4060cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			 root, kversion);
4070cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		dirname = dirname_buf;
4080cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
4090cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
4100cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	ctx = kmod_new(dirname, &null_config);
4110cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (!ctx) {
4120cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		fputs("Error: kmod_new() failed!\n", stderr);
4130cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		return EXIT_FAILURE;
4140cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
4150cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	kmod_load_resources(ctx);
4160cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
4170cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	err = 0;
4180cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	for (i = optind; i < argc; i++) {
4190cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		const char *name = argv[i];
4200cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		struct stat st;
4210cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		int r;
4220cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
4230cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (stat(name, &st) == 0 && S_ISREG(st.st_mode))
4240cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			r = modinfo_path_do(ctx, name);
4250cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		else
4260cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			r = modinfo_alias_do(ctx, name);
4270cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
4280cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (r < 0)
4290cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			err = r;
4300cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
4310cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
4320cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	kmod_unref(ctx);
4330cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	return err >= 0 ? EXIT_SUCCESS : EXIT_FAILURE;
4340cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri}
435