modinfo.c revision 9382dbf7aa8e65b3e080f154b7b986da0e1fbfce
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
319382dbf7aa8e65b3e080f154b7b986da0e1fbfceLucas De Marchi#define LOGPREFIX "modinfo: "
329382dbf7aa8e65b3e080f154b7b986da0e1fbfceLucas De Marchi#define ERR(...) fprintf(stderr, LOGPREFIX "ERROR: " __VA_ARGS__)
330cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
340cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic char separator = '\n';
350cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic const char *field = NULL;
360cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
370cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristruct param {
380cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	struct param *next;
390cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	const char *name;
400cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	const char *param;
410cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	const char *type;
420cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	int namelen;
430cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	int paramlen;
440cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	int typelen;
450cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri};
460cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
470cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic struct param *add_param(const char *name, int namelen, const char *param, int paramlen, const char *type, int typelen, struct param **list)
480cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri{
490cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	struct param *it;
500cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
510cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	for (it = *list; it != NULL; it = it->next) {
520cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (it->namelen == namelen &&
530cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			memcmp(it->name, name, namelen) == 0)
540cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
550cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
560cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
570cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (it == NULL) {
580cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it = malloc(sizeof(struct param));
590cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (it == NULL)
600cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			return NULL;
610cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->next = *list;
620cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		*list = it;
630cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->name = name;
640cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->namelen = namelen;
650cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->param = NULL;
660cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->type = NULL;
670cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->paramlen = 0;
680cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->typelen = 0;
690cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
700cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
710cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (param != NULL) {
720cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->param = param;
730cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->paramlen = paramlen;
740cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
750cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
760cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (type != NULL) {
770cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->type = type;
780cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		it->typelen = typelen;
790cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
800cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
810cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	return it;
820cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri}
830cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
84b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieristatic int process_parm(const char *key, const char *value, struct param **params)
85b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri{
86b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	const char *name, *param, *type;
87b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	int namelen, paramlen, typelen;
88b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	struct param *it;
89b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	const char *colon = strchr(value, ':');
90b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	if (colon == NULL) {
919382dbf7aa8e65b3e080f154b7b986da0e1fbfceLucas De Marchi		ERR("Found invalid \"%s=%s\": missing ':'\n",
92b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		    key, value);
93b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		return 0;
94b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	}
95b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
96b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	name = value;
97b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	namelen = colon - value;
98b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	if (strcmp(key, "parm") == 0) {
99b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		param = colon + 1;
100b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		paramlen = strlen(param);
101b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		type = NULL;
102b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		typelen = 0;
103b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	} else {
104b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		param = NULL;
105b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		paramlen = 0;
106b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		type = colon + 1;
107b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		typelen = strlen(type);
108b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	}
109b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
110b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	it = add_param(name, namelen, param, paramlen, type, typelen, params);
111b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	if (it == NULL) {
1129382dbf7aa8e65b3e080f154b7b986da0e1fbfceLucas De Marchi		ERR("Out of memory!\n");
113b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		return -ENOMEM;
114b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	}
115b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
116b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	return 0;
117b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri}
118b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
119b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieristatic int modinfo_params_do(const struct kmod_list *list)
120b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri{
121b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	const struct kmod_list *l;
122b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	struct param *params = NULL;
123b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	int err = 0;
124b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
125b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	kmod_list_foreach(l, list) {
126b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		const char *key = kmod_module_info_get_key(l);
127b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		const char *value = kmod_module_info_get_value(l);
128b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		if (strcmp(key, "parm") != 0 &&
129b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		    strcmp(key, "parmtype") != 0)
130b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			continue;
131b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
132b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		err = process_parm(key, value, &params);
133b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		if (err < 0)
134b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			goto end;
135b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	}
136b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
137b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	while (params != NULL) {
138b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		struct param *p = params;
139b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		params = p->next;
140b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
141b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		if (p->param == NULL)
142b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			printf("%.*s: (%.*s)%c",
143b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       p->namelen, p->name, p->typelen, p->type,
144b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       separator);
145b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		else if (p->type != NULL)
146b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			printf("%.*s:%.*s (%.*s)%c",
147b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       p->namelen, p->name,
148b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       p->paramlen, p->param,
149b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       p->typelen, p->type,
150b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       separator);
151b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		else
152b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			printf("%.*s:%.*s%c",
153b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       p->namelen, p->name,
154b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       p->paramlen, p->param,
155b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			       separator);
156b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
157b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		free(p);
158b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	}
159b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
160b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieriend:
161b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	while (params != NULL) {
162b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		void *tmp = params;
163b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		params = params->next;
164b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		free(tmp);
165b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	}
166b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
167b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	return err;
168b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri}
169b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
1700cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic int modinfo_do(struct kmod_module *mod)
1710cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri{
1720cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	struct kmod_list *l, *list = NULL;
1730cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	struct param *params = NULL;
1740cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	int err;
1750cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
1760cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (field != NULL && strcmp(field, "filename") == 0) {
1770cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		printf("%s%c", kmod_module_get_path(mod), separator);
1780cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		return 0;
1790cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	} else if (field == NULL) {
1800cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		printf("%-16s%s%c", "filename:",
1810cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		       kmod_module_get_path(mod), separator);
1820cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
1830cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
1840cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	err = kmod_module_get_info(mod, &list);
1850cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (err < 0) {
1869382dbf7aa8e65b3e080f154b7b986da0e1fbfceLucas De Marchi		ERR("could not get modinfo from '%s': %s\n",
1870cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			kmod_module_get_name(mod), strerror(-err));
1880cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		return err;
1890cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
1900cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
191b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	if (field != NULL && strcmp(field, "parm") == 0) {
192b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		err = modinfo_params_do(list);
193b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri		goto end;
194b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri	}
195b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri
1960cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	kmod_list_foreach(l, list) {
1970cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		const char *key = kmod_module_info_get_key(l);
1980cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		const char *value = kmod_module_info_get_value(l);
1990cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		int keylen;
2000cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2010cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (field != NULL) {
2020cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			if (strcmp(field, key) != 0)
2030cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri				continue;
2040cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			/* filtered output contains no key, just value */
2050cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			printf("%s%c", value, separator);
2060cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			continue;
2070cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		}
2080cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2090cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (strcmp(key, "parm") == 0 || strcmp(key, "parmtype") == 0) {
210b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			err = process_parm(key, value, &params);
211b014c490cb7dc1dd064393537c69ed5fd7b81ccfGustavo Sverzut Barbieri			if (err < 0)
2120cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri				goto end;
2130cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			continue;
2140cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		}
2150cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2160cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (separator == '\0') {
2170cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			printf("%s=%s%c", key, value, separator);
2180cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			continue;
2190cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		}
2200cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2210cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		keylen = strlen(key);
2220cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		printf("%s:%-*s%s%c", key, 15 - keylen, "", value, separator);
2230cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
2240cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2250cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (field != NULL)
2260cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		goto end;
2270cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2280cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	while (params != NULL) {
2290cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		struct param *p = params;
2300cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		params = p->next;
2310cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2320cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (p->param == NULL)
2330cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			printf("%-16s%.*s:%.*s%c", "parm:",
2340cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       p->namelen, p->name, p->typelen, p->type,
2350cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       separator);
2360cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		else if (p->type != NULL)
237515ec7960bf22c52e9e5d27c23a5dadad785a9daGustavo Sverzut Barbieri			printf("%-16s%.*s:%.*s (%.*s)%c", "parm:",
2380cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       p->namelen, p->name,
2390cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       p->paramlen, p->param,
2400cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       p->typelen, p->type,
2410cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       separator);
2420cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		else
243515ec7960bf22c52e9e5d27c23a5dadad785a9daGustavo Sverzut Barbieri			printf("%-16s%.*s:%.*s%c",
2440cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       "parm:",
2450cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       p->namelen, p->name,
2460cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       p->paramlen, p->param,
2470cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			       separator);
2480cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2490cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		free(p);
2500cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
2510cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2520cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieriend:
2530cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	while (params != NULL) {
2540cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		void *tmp = params;
2550cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		params = params->next;
2560cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		free(tmp);
2570cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
2580cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	kmod_module_info_free_list(list);
2590cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2600cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	return err;
2610cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri}
2620cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2630cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic int modinfo_path_do(struct kmod_ctx *ctx, const char *path)
2640cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri{
2650cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	struct kmod_module *mod;
2660cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	int err = kmod_module_new_from_path(ctx, path, &mod);
2670cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (err < 0) {
2689382dbf7aa8e65b3e080f154b7b986da0e1fbfceLucas De Marchi		ERR("Module file %s not found.\n", path);
2690cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		return err;
2700cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
2710cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	err = modinfo_do(mod);
2720cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	kmod_module_unref(mod);
2730cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	return err;
2740cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri}
2750cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
2760cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic int modinfo_alias_do(struct kmod_ctx *ctx, const char *alias)
2770cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri{
2783e4c6af6ad41182ab3efc5ebe796005648ba4733Dave Reisner	struct kmod_list *l, *filtered, *list = NULL;
2790cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	int err = kmod_module_new_from_lookup(ctx, alias, &list);
2800cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (err < 0) {
2819382dbf7aa8e65b3e080f154b7b986da0e1fbfceLucas De Marchi		ERR("Module alias %s not found.\n", alias);
2820cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		return err;
2830cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
2845f85a133f8e4c2c97f90062e4055dbe2efd76325Dave Reisner
2855f85a133f8e4c2c97f90062e4055dbe2efd76325Dave Reisner	if (list == NULL) {
2869382dbf7aa8e65b3e080f154b7b986da0e1fbfceLucas De Marchi		ERR("Module %s not found.\n", alias);
2875f85a133f8e4c2c97f90062e4055dbe2efd76325Dave Reisner		return -ENOENT;
2885f85a133f8e4c2c97f90062e4055dbe2efd76325Dave Reisner	}
2895f85a133f8e4c2c97f90062e4055dbe2efd76325Dave Reisner
2903e4c6af6ad41182ab3efc5ebe796005648ba4733Dave Reisner	err = kmod_module_apply_filter(ctx, KMOD_FILTER_BUILTIN, list, &filtered);
2913e4c6af6ad41182ab3efc5ebe796005648ba4733Dave Reisner	kmod_module_unref_list(list);
2923e4c6af6ad41182ab3efc5ebe796005648ba4733Dave Reisner	if (err < 0) {
2939382dbf7aa8e65b3e080f154b7b986da0e1fbfceLucas De Marchi		ERR("Failed to filter list: %m\n");
2943e4c6af6ad41182ab3efc5ebe796005648ba4733Dave Reisner		return err;
2953e4c6af6ad41182ab3efc5ebe796005648ba4733Dave Reisner	}
2963e4c6af6ad41182ab3efc5ebe796005648ba4733Dave Reisner
2973e4c6af6ad41182ab3efc5ebe796005648ba4733Dave Reisner	if (filtered == NULL) {
2989382dbf7aa8e65b3e080f154b7b986da0e1fbfceLucas De Marchi		ERR("Module %s not found.\n", alias);
2993e4c6af6ad41182ab3efc5ebe796005648ba4733Dave Reisner		return -ENOENT;
3003e4c6af6ad41182ab3efc5ebe796005648ba4733Dave Reisner	}
3013e4c6af6ad41182ab3efc5ebe796005648ba4733Dave Reisner
3023e4c6af6ad41182ab3efc5ebe796005648ba4733Dave Reisner	kmod_list_foreach(l, filtered) {
3030cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		struct kmod_module *mod = kmod_module_get_module(l);
3040cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		int r = modinfo_do(mod);
3050cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		kmod_module_unref(mod);
3060cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (r < 0)
3070cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			err = r;
3080cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
3093e4c6af6ad41182ab3efc5ebe796005648ba4733Dave Reisner	kmod_module_unref_list(filtered);
3100cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	return err;
3110cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri}
3120cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
313022e1f0e0dae85772fc56604d3c009c23391bc10Gustavo Sverzut Barbieristatic const char cmdopts_s[] = "adlpn0F:k:b:Vh";
3140cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic const struct option cmdopts[] = {
3150cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"author", no_argument, 0, 'a'},
3160cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"description", no_argument, 0, 'd'},
3170cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"license", no_argument, 0, 'l'},
3180cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"parameters", no_argument, 0, 'p'},
3190cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"filename", no_argument, 0, 'n'},
3200cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"null", no_argument, 0, '0'},
3210cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"field", required_argument, 0, 'F'},
3220cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"set-version", required_argument, 0, 'k'},
3230cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"basedir", required_argument, 0, 'b'},
3240cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"version", no_argument, 0, 'V'},
3250cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{"help", no_argument, 0, 'h'},
3260cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	{NULL, 0, 0, 0}
3270cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri};
3280cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
3290cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieristatic void help(const char *progname)
3300cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri{
3310cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	fprintf(stderr,
3320cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"Usage:\n"
3330cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t%s [options] filename [args]\n"
3340cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"Options:\n"
3350cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-a, --author                Print only 'author'\n"
3360cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-d, --description           Print only 'description'\n"
3370cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-l, --license               Print only 'license'\n"
3380cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-p, --parameters            Print only 'parm'\n"
3390cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-n, --filename              Print only 'filename'\n"
3400cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-0, --null                  Use \\0 instead of \\n\n"
3410cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-F, --field=FIELD           Print only provided FIELD\n"
3420cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-k, --set-version=VERSION   Use VERSION instead of `uname -r`\n"
343c5b37dba8956dd8f82c54b9f97dc5dca07940db5Dave Reisner		"\t-b, --basedir=DIR           Use DIR as filesystem root for /lib/modules\n"
3440cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-V, --version               Show version\n"
3450cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		"\t-h, --help                  Show this help\n",
3460cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		progname);
3470cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri}
3480cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
349a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGeestatic bool is_module_filename(const char *name)
350a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee{
351a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee	struct stat st;
352a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee	const char *ptr;
353a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee
354a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee	if (stat(name, &st) == 0 && S_ISREG(st.st_mode) &&
355a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee					(ptr = strstr(name, ".ko")) != NULL) {
356a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee		/*
357a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee		 * We screened for .ko; make sure this is either at the end of
358a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee		 * the name or followed by another '.' (e.g. gz or xz modules)
359a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee		 */
360a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee		if(ptr[3] == '\0' || ptr[3] == '.')
361a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee			return true;
362a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee	}
363a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee
364a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee	return false;
365a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee}
366a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee
367769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchistatic int do_modinfo(int argc, char *argv[])
3680cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri{
3690cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	struct kmod_ctx *ctx;
3700cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	char dirname_buf[PATH_MAX];
3710cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	const char *dirname = NULL;
3720cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	const char *kversion = NULL;
3730cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	const char *root = NULL;
3740cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	const char *null_config = NULL;
3750cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	int i, err;
3760cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
3770cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	for (;;) {
3780cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		int c, idx = 0;
3790cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		c = getopt_long(argc, argv, cmdopts_s, cmdopts, &idx);
3800cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (c == -1)
3810cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3820cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		switch (c) {
3830cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'a':
3840cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			field = "author";
3850cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3860cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'd':
3870cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			field = "description";
3880cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3890cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'l':
3900cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			field = "license";
3910cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3920cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'p':
3930cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			field = "parm";
3940cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3950cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'n':
3960cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			field = "filename";
3970cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
3980cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case '0':
3990cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			separator = '\0';
4000cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
4010cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'F':
4020cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			field = optarg;
4030cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
4040cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'k':
4050cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			kversion = optarg;
4060cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
4070cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'b':
4080cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			root = optarg;
4090cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			break;
4100cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'h':
411aa156c98608778140f95ae0dfb29bbd113e9ca5bLucas De Marchi			help(basename(argv[0]));
4120cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			return EXIT_SUCCESS;
4130cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case 'V':
4140cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			puts(PACKAGE " version " VERSION);
4150cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			return EXIT_SUCCESS;
4160cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		case '?':
4170cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			return EXIT_FAILURE;
4180cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		default:
4199382dbf7aa8e65b3e080f154b7b986da0e1fbfceLucas De Marchi			ERR("unexpected getopt_long() value '%c'.\n", c);
4200cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			return EXIT_FAILURE;
4210cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		}
4220cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
4230cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
4240cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (optind >= argc) {
4259382dbf7aa8e65b3e080f154b7b986da0e1fbfceLucas De Marchi		ERR("missing module or filename.\n");
4260cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		return EXIT_FAILURE;
4270cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
4280cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
4290cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (root != NULL || kversion != NULL) {
4300cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		struct utsname u;
4310cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (root == NULL)
4320cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			root = "";
4330cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (kversion == NULL) {
4340cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			if (uname(&u) < 0) {
4359382dbf7aa8e65b3e080f154b7b986da0e1fbfceLucas De Marchi				ERR("uname() failed: %m\n");
4360cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri				return EXIT_FAILURE;
4370cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			}
4380cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			kversion = u.release;
4390cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		}
440c5b37dba8956dd8f82c54b9f97dc5dca07940db5Dave Reisner		snprintf(dirname_buf, sizeof(dirname_buf), "%s/lib/modules/%s",
4410cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			 root, kversion);
4420cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		dirname = dirname_buf;
4430cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
4440cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
4450cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	ctx = kmod_new(dirname, &null_config);
4460cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	if (!ctx) {
4479382dbf7aa8e65b3e080f154b7b986da0e1fbfceLucas De Marchi		ERR("kmod_new() failed!\n");
4480cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		return EXIT_FAILURE;
4490cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
4500cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
4510cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	err = 0;
4520cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	for (i = optind; i < argc; i++) {
4530cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		const char *name = argv[i];
4540cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		int r;
4550cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
456a23f0c9c55f46635cb58e5269b19b9e4471b5150Dan McGee		if (is_module_filename(name))
4570cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			r = modinfo_path_do(ctx, name);
4580cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		else
4590cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			r = modinfo_alias_do(ctx, name);
4600cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
4610cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri		if (r < 0)
4620cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri			err = r;
4630cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	}
4640cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri
4650cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	kmod_unref(ctx);
4660cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri	return err >= 0 ? EXIT_SUCCESS : EXIT_FAILURE;
4670cc3ccfd5233e03506b41022e4a31a37e8a208acGustavo Sverzut Barbieri}
468769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchi
469769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchi#include "kmod.h"
470769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchi
471769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchiconst struct kmod_cmd kmod_cmd_compat_modinfo = {
472769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchi	.name = "modinfo",
473769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchi	.cmd = do_modinfo,
474769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchi	.help = "compat modinfo command",
475769becb5dbfb673900c6813d02ae3737d87035efLucas De Marchi};
476