modinfo.c revision a23f0c9c55f46635cb58e5269b19b9e4471b5150
10cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri/*
20cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri * kmod-modinfo - query kernel module information using libkmod.
30cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri *
4a66a6a999f0156f5c43bc51660300f9a7466986fLucas De Marchi * Copyright (C) 2011-2012  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>
22a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee#include <stdbool.h>
230cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri#include <getopt.h>
240cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri#include <errno.h>
250cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri#include <string.h>
260cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri#include <limits.h>
270cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri#include <sys/utsname.h>
280cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri#include <sys/stat.h>
290cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri#include "libkmod.h"
300cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
310cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri#define LOG(fmt, ...) fprintf(stderr, "ERROR: "fmt, ##__VA_ARGS__)
320cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
330cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic char separator = '\n';
340cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic const char *field = NULL;
350cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
360cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristruct param {
370cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	struct param *next;
380cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	const char *name;
390cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	const char *param;
400cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	const char *type;
410cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	int namelen;
420cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	int paramlen;
430cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	int typelen;
440cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri};
450cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
460cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic struct param *add_param(const char *name, int namelen, const char *param, int paramlen, const char *type, int typelen, struct param **list)
470cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri{
480cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	struct param *it;
490cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
500cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	for (it = *list; it != NULL; it = it->next) {
510cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (it->namelen == namelen &&
520cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			memcmp(it->name, name, namelen) == 0)
530cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
540cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
550cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
560cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (it == NULL) {
570cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it = malloc(sizeof(struct param));
580cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (it == NULL)
590cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			return NULL;
600cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->next = *list;
610cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		*list = it;
620cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->name = name;
630cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->namelen = namelen;
640cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->param = NULL;
650cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->type = NULL;
660cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->paramlen = 0;
670cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->typelen = 0;
680cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
690cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
700cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (param != NULL) {
710cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->param = param;
720cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->paramlen = paramlen;
730cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
740cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
750cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (type != NULL) {
760cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->type = type;
770cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->typelen = typelen;
780cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
790cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
800cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	return it;
810cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri}
820cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
83b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieristatic int process_parm(const char *key, const char *value, struct param **params)
84b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri{
85b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	const char *name, *param, *type;
86b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	int namelen, paramlen, typelen;
87b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	struct param *it;
88b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	const char *colon = strchr(value, ':');
89b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	if (colon == NULL) {
90b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		LOG("Found invalid \"%s=%s\": missing ':'\n",
91b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		    key, value);
92b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		return 0;
93b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	}
94b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
95b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	name = value;
96b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	namelen = colon - value;
97b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	if (strcmp(key, "parm") == 0) {
98b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		param = colon + 1;
99b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		paramlen = strlen(param);
100b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		type = NULL;
101b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		typelen = 0;
102b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	} else {
103b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		param = NULL;
104b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		paramlen = 0;
105b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		type = colon + 1;
106b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		typelen = strlen(type);
107b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	}
108b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
109b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	it = add_param(name, namelen, param, paramlen, type, typelen, params);
110b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	if (it == NULL) {
111b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		LOG("Out of memory!\n");
112b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		return -ENOMEM;
113b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	}
114b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
115b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	return 0;
116b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri}
117b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
118b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieristatic int modinfo_params_do(const struct kmod_list *list)
119b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri{
120b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	const struct kmod_list *l;
121b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	struct param *params = NULL;
122b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	int err = 0;
123b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
124b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	kmod_list_foreach(l, list) {
125b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		const char *key = kmod_module_info_get_key(l);
126b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		const char *value = kmod_module_info_get_value(l);
127b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		if (strcmp(key, "parm") != 0 &&
128b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		    strcmp(key, "parmtype") != 0)
129b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			continue;
130b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
131b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		err = process_parm(key, value, &params);
132b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		if (err < 0)
133b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			goto end;
134b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	}
135b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
136b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	while (params != NULL) {
137b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		struct param *p = params;
138b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		params = p->next;
139b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
140b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		if (p->param == NULL)
141b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			printf("%.*s: (%.*s)%c",
142b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       p->namelen, p->name, p->typelen, p->type,
143b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       separator);
144b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		else if (p->type != NULL)
145b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			printf("%.*s:%.*s (%.*s)%c",
146b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       p->namelen, p->name,
147b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       p->paramlen, p->param,
148b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       p->typelen, p->type,
149b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       separator);
150b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		else
151b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			printf("%.*s:%.*s%c",
152b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       p->namelen, p->name,
153b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       p->paramlen, p->param,
154b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       separator);
155b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
156b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		free(p);
157b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	}
158b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
159b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieriend:
160b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	while (params != NULL) {
161b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		void *tmp = params;
162b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		params = params->next;
163b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		free(tmp);
164b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	}
165b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
166b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	return err;
167b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri}
168b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
1690cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic int modinfo_do(struct kmod_module *mod)
1700cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri{
1710cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	struct kmod_list *l, *list = NULL;
1720cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	struct param *params = NULL;
1730cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	int err;
1740cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
1750cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (field != NULL && strcmp(field, "filename") == 0) {
1760cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		printf("%s%c", kmod_module_get_path(mod), separator);
1770cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		return 0;
1780cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	} else if (field == NULL) {
1790cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		printf("%-16s%s%c", "filename:",
1800cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		       kmod_module_get_path(mod), separator);
1810cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
1820cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
1830cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	err = kmod_module_get_info(mod, &list);
1840cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (err < 0) {
185636983770760f0f7b29db90d4733779f2bae6045Dave Reisner		LOG("could not get modinfo from '%s': %s\n",
1860cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			kmod_module_get_name(mod), strerror(-err));
1870cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		return err;
1880cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
1890cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
190b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	if (field != NULL && strcmp(field, "parm") == 0) {
191b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		err = modinfo_params_do(list);
192b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		goto end;
193b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	}
194b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
1950cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	kmod_list_foreach(l, list) {
1960cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		const char *key = kmod_module_info_get_key(l);
1970cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		const char *value = kmod_module_info_get_value(l);
1980cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		int keylen;
1990cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2000cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (field != NULL) {
2010cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			if (strcmp(field, key) != 0)
2020cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri				continue;
2030cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			/* filtered output contains no key, just value */
2040cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			printf("%s%c", value, separator);
2050cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			continue;
2060cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		}
2070cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2080cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (strcmp(key, "parm") == 0 || strcmp(key, "parmtype") == 0) {
209b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			err = process_parm(key, value, &params);
210b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			if (err < 0)
2110cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri				goto end;
2120cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			continue;
2130cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		}
2140cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2150cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (separator == '\0') {
2160cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			printf("%s=%s%c", key, value, separator);
2170cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			continue;
2180cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		}
2190cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2200cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		keylen = strlen(key);
2210cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		printf("%s:%-*s%s%c", key, 15 - keylen, "", value, separator);
2220cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
2230cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2240cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (field != NULL)
2250cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		goto end;
2260cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2270cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	while (params != NULL) {
2280cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		struct param *p = params;
2290cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		params = p->next;
2300cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2310cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (p->param == NULL)
2320cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			printf("%-16s%.*s:%.*s%c", "parm:",
2330cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       p->namelen, p->name, p->typelen, p->type,
2340cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       separator);
2350cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		else if (p->type != NULL)
236515ec7960bf22c52e9e5d27c23a5dadad785a9daGustavo Sverzut Barbieri			printf("%-16s%.*s:%.*s (%.*s)%c", "parm:",
2370cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       p->namelen, p->name,
2380cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       p->paramlen, p->param,
2390cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       p->typelen, p->type,
2400cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       separator);
2410cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		else
242515ec7960bf22c52e9e5d27c23a5dadad785a9daGustavo Sverzut Barbieri			printf("%-16s%.*s:%.*s%c",
2430cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       "parm:",
2440cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       p->namelen, p->name,
2450cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       p->paramlen, p->param,
2460cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       separator);
2470cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2480cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		free(p);
2490cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
2500cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2510cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieriend:
2520cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	while (params != NULL) {
2530cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		void *tmp = params;
2540cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		params = params->next;
2550cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		free(tmp);
2560cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
2570cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	kmod_module_info_free_list(list);
2580cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2590cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	return err;
2600cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri}
2610cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2620cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic int modinfo_path_do(struct kmod_ctx *ctx, const char *path)
2630cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri{
2640cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	struct kmod_module *mod;
2650cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	int err = kmod_module_new_from_path(ctx, path, &mod);
2660cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (err < 0) {
2670cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		LOG("Module file %s not found.\n", path);
2680cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		return err;
2690cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
2700cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	err = modinfo_do(mod);
2710cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	kmod_module_unref(mod);
2720cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	return err;
2730cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri}
2740cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2750cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic int modinfo_alias_do(struct kmod_ctx *ctx, const char *alias)
2760cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri{
2770cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	struct kmod_list *l, *list = NULL;
2780cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	int err = kmod_module_new_from_lookup(ctx, alias, &list);
2790cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (err < 0) {
2800cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		LOG("Module alias %s not found.\n", alias);
2810cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		return err;
2820cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
2835f85a133f8e4c2c97f90062e4055dbe2efd76325Dave Reisner
2845f85a133f8e4c2c97f90062e4055dbe2efd76325Dave Reisner	if (list == NULL) {
2855f85a133f8e4c2c97f90062e4055dbe2efd76325Dave Reisner		LOG("Module %s not found.\n", alias);
2865f85a133f8e4c2c97f90062e4055dbe2efd76325Dave Reisner		return -ENOENT;
2875f85a133f8e4c2c97f90062e4055dbe2efd76325Dave Reisner	}
2885f85a133f8e4c2c97f90062e4055dbe2efd76325Dave Reisner
2890cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	kmod_list_foreach(l, list) {
2900cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		struct kmod_module *mod = kmod_module_get_module(l);
2910cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		int r = modinfo_do(mod);
2920cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		kmod_module_unref(mod);
2930cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (r < 0)
2940cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			err = r;
2950cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
2960cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	kmod_module_unref_list(list);
2970cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	return err;
2980cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri}
2990cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
300022e1f0e0dae85772fc56604d3c009c23391bc10Gustavo Sverzut Barbieristatic const char cmdopts_s[] = "adlpn0F:k:b:Vh";
3010cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic const struct option cmdopts[] = {
3020cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"author", no_argument, 0, 'a'},
3030cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"description", no_argument, 0, 'd'},
3040cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"license", no_argument, 0, 'l'},
3050cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"parameters", no_argument, 0, 'p'},
3060cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"filename", no_argument, 0, 'n'},
3070cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"null", no_argument, 0, '0'},
3080cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"field", required_argument, 0, 'F'},
3090cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"set-version", required_argument, 0, 'k'},
3100cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"basedir", required_argument, 0, 'b'},
3110cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"version", no_argument, 0, 'V'},
3120cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"help", no_argument, 0, 'h'},
3130cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{NULL, 0, 0, 0}
3140cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri};
3150cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
3160cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic void help(const char *progname)
3170cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri{
3180cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	fprintf(stderr,
3190cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"Usage:\n"
3200cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t%s [options] filename [args]\n"
3210cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"Options:\n"
3220cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-a, --author                Print only 'author'\n"
3230cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-d, --description           Print only 'description'\n"
3240cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-l, --license               Print only 'license'\n"
3250cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-p, --parameters            Print only 'parm'\n"
3260cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-n, --filename              Print only 'filename'\n"
3270cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-0, --null                  Use \\0 instead of \\n\n"
3280cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-F, --field=FIELD           Print only provided FIELD\n"
3290cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-k, --set-version=VERSION   Use VERSION instead of `uname -r`\n"
330a308abec371364eec8344681cfe1fb50d624e43eKay Sievers		"\t-b, --basedir=DIR           Use DIR as filesystem root for " ROOTPREFIX "/lib/modules\n"
3310cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-V, --version               Show version\n"
3320cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-h, --help                  Show this help\n",
3330cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		progname);
3340cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri}
3350cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
336a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGeestatic bool is_module_filename(const char *name)
337a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee{
338a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee	struct stat st;
339a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee	const char *ptr;
340a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee
341a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee	if (stat(name, &st) == 0 && S_ISREG(st.st_mode) &&
342a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee					(ptr = strstr(name, ".ko")) != NULL) {
343a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee		/*
344a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee		 * We screened for .ko; make sure this is either at the end of
345a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee		 * the name or followed by another '.' (e.g. gz or xz modules)
346a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee		 */
347a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee		if(ptr[3] == '\0' || ptr[3] == '.')
348a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee			return true;
349a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee	}
350a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee
351a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee	return false;
352a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee}
353a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee
354769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchistatic int do_modinfo(int argc, char *argv[])
3550cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri{
3560cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	struct kmod_ctx *ctx;
3570cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	char dirname_buf[PATH_MAX];
3580cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	const char *dirname = NULL;
3590cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	const char *kversion = NULL;
3600cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	const char *root = NULL;
3610cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	const char *null_config = NULL;
3620cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	int i, err;
3630cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
3640cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	for (;;) {
3650cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		int c, idx = 0;
3660cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		c = getopt_long(argc, argv, cmdopts_s, cmdopts, &idx);
3670cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (c == -1)
3680cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3690cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		switch (c) {
3700cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'a':
3710cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			field = "author";
3720cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3730cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'd':
3740cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			field = "description";
3750cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3760cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'l':
3770cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			field = "license";
3780cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3790cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'p':
3800cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			field = "parm";
3810cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3820cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'n':
3830cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			field = "filename";
3840cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3850cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case '0':
3860cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			separator = '\0';
3870cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3880cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'F':
3890cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			field = optarg;
3900cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3910cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'k':
3920cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			kversion = optarg;
3930cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3940cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'b':
3950cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			root = optarg;
3960cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3970cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'h':
398aa156c98608778140f95ae0dfb29bbd113e9ca5bLucas De Marchi			help(basename(argv[0]));
3990cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			return EXIT_SUCCESS;
4000cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'V':
4010cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			puts(PACKAGE " version " VERSION);
4020cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			return EXIT_SUCCESS;
4030cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case '?':
4040cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			return EXIT_FAILURE;
4050cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		default:
4060cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			fprintf(stderr,
4070cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri				"Error: unexpected getopt_long() value '%c'.\n",
4080cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri				c);
4090cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			return EXIT_FAILURE;
4100cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		}
4110cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
4120cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
4130cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (optind >= argc) {
4140cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		fprintf(stderr, "Error: missing module or filename.\n");
4150cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		return EXIT_FAILURE;
4160cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
4170cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
4180cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (root != NULL || kversion != NULL) {
4190cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		struct utsname u;
4200cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (root == NULL)
4210cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			root = "";
4220cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (kversion == NULL) {
4230cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			if (uname(&u) < 0) {
4240cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri				fprintf(stderr, "Error: uname() failed: %s\n",
4250cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri					strerror(errno));
4260cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri				return EXIT_FAILURE;
4270cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			}
4280cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			kversion = u.release;
4290cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		}
430a308abec371364eec8344681cfe1fb50d624e43eKay Sievers		snprintf(dirname_buf, sizeof(dirname_buf), "%s" ROOTPREFIX "/lib/modules/%s",
4310cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			 root, kversion);
4320cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		dirname = dirname_buf;
4330cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
4340cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
4350cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	ctx = kmod_new(dirname, &null_config);
4360cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (!ctx) {
4370cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		fputs("Error: kmod_new() failed!\n", stderr);
4380cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		return EXIT_FAILURE;
4390cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
4400cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
4410cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	err = 0;
4420cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	for (i = optind; i < argc; i++) {
4430cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		const char *name = argv[i];
4440cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		int r;
4450cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
446a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee		if (is_module_filename(name))
4470cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			r = modinfo_path_do(ctx, name);
4480cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		else
4490cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			r = modinfo_alias_do(ctx, name);
4500cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
4510cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (r < 0)
4520cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			err = r;
4530cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
4540cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
4550cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	kmod_unref(ctx);
4560cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	return err >= 0 ? EXIT_SUCCESS : EXIT_FAILURE;
4570cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri}
458769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchi
459769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchi#ifndef KMOD_BUNDLE_TOOL
460769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchiint main(int argc, char *argv[])
461769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchi{
462769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchi	return do_modinfo(argc, argv);
463769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchi}
464769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchi
465769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchi#else
466769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchi#include "kmod.h"
467769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchi
468769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchiconst struct kmod_cmd kmod_cmd_compat_modinfo = {
469769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchi	.name = "modinfo",
470769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchi	.cmd = do_modinfo,
471769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchi	.help = "compat modinfo command",
472769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchi};
473769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchi
474769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchi#endif
475