]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sbin/kldstat/kldstat.c
MFV r326007: less v529.
[FreeBSD/FreeBSD.git] / sbin / kldstat / kldstat.c
1 /*-
2  * Copyright (c) 1997 Doug Rabson
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29
30 #include <err.h>
31 #include <libutil.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include <sys/types.h>
36 #include <sys/param.h>
37 #include <sys/module.h>
38 #include <sys/linker.h>
39 #include <strings.h>
40
41 #define POINTER_WIDTH   ((int)(sizeof(void *) * 2 + 2))
42
43 static int showdata = 0;
44
45 static void
46 printmod(int modid)
47 {
48     struct module_stat stat;
49
50     bzero(&stat, sizeof(stat));
51     stat.version = sizeof(struct module_stat);
52     if (modstat(modid, &stat) < 0)
53         warn("can't stat module id %d", modid);
54     else
55         if (showdata) {
56             printf("\t\t%2d %s (%d, %u, 0x%lx)\n", stat.id, stat.name, 
57                 stat.data.intval, stat.data.uintval, stat.data.ulongval);
58         } else {
59                 printf("\t\t%2d %s\n", stat.id, stat.name);
60         }
61 }
62
63 static void
64 printfile(int fileid, int verbose, int humanized)
65 {
66     struct kld_file_stat stat;
67     int modid;
68     char buf[5];
69
70     stat.version = sizeof(struct kld_file_stat);
71     if (kldstat(fileid, &stat) < 0) {
72         err(1, "can't stat file id %d", fileid);
73     } else {
74         if (humanized) {
75                humanize_number(buf, sizeof(buf), stat.size,
76                    "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE);
77
78                printf("%2d %4d %p %5s %s",
79                    stat.id, stat.refs, stat.address, buf, stat.name);
80         } else {
81                 printf("%2d %4d %p %-8zx %s",
82                     stat.id, stat.refs, stat.address, stat.size, stat.name);
83         }
84     }
85
86     if (verbose) {
87         printf(" (%s)\n", stat.pathname);
88         printf("\tContains modules:\n");
89         printf("\t\tId Name\n");
90         for (modid = kldfirstmod(fileid); modid > 0;
91              modid = modfnext(modid))
92             printmod(modid);
93     } else
94         printf("\n");
95 }
96
97 static void
98 usage(void)
99 {
100     fprintf(stderr, "usage: kldstat [-d] [-h] [-q] [-v] [-i id] [-n filename]\n");
101     fprintf(stderr, "       kldstat [-d] [-q] [-m modname]\n");
102     exit(1);
103 }
104
105 int
106 main(int argc, char** argv)
107 {
108     int c;
109     int humanized = 0;
110     int verbose = 0;
111     int fileid = 0;
112     int quiet = 0;
113     char* filename = NULL;
114     char* modname = NULL;
115     char* p;
116
117     while ((c = getopt(argc, argv, "dhi:m:n:qv")) != -1)
118         switch (c) {
119         case 'd':
120             showdata = 1;
121             break;
122         case 'h':
123             humanized = 1;
124             break;
125         case 'i':
126             fileid = (int)strtoul(optarg, &p, 10);
127             if (*p != '\0')
128                 usage();
129             break;
130         case 'm':
131             modname = optarg;
132             break;
133         case 'n':
134             filename = optarg;
135             break;
136         case 'q':
137             quiet = 1;
138             break;
139         case 'v':
140             verbose = 1;
141             break;
142         default:
143             usage();
144         }
145     argc -= optind;
146     argv += optind;
147
148     if (argc != 0)
149         usage();
150
151     if (modname != NULL) {
152         int modid;
153         struct module_stat stat;
154
155         if ((modid = modfind(modname)) < 0) {
156             if (!quiet)
157                 warn("can't find module %s", modname);
158             return 1;
159         } else if (quiet) {
160             return 0;
161         }
162
163         stat.version = sizeof(struct module_stat);
164         if (modstat(modid, &stat) < 0)
165             warn("can't stat module id %d", modid);
166         else {
167                 if (showdata) {
168                     printf("Id  Refs Name data..(int, uint, ulong)\n");
169                     printf("%3d %4d %s (%d, %u, 0x%lx)\n", stat.id, stat.refs, stat.name, 
170                         stat.data.intval, stat.data.uintval, stat.data.ulongval);
171                 } else {
172                     printf("Id  Refs Name\n");
173                     printf("%3d %4d %s\n", stat.id, stat.refs, stat.name);
174                 }
175         }
176
177         return 0;
178     }
179
180     if (filename != NULL) {
181         if ((fileid = kldfind(filename)) < 0) {
182             if (!quiet)
183                 warn("can't find file %s", filename);
184             return 1;
185         } else if (quiet) {
186             return 0;
187         }
188     }
189
190     if (humanized)
191             printf("Id Refs Address%*c  Size Name\n", POINTER_WIDTH - 7, ' ');
192     else
193             printf("Id Refs Address%*c Size     Name\n", POINTER_WIDTH - 7, ' ');
194     if (fileid != 0)
195         printfile(fileid, verbose, humanized);
196     else
197         for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid))
198             printfile(fileid, verbose, humanized);
199
200     return 0;
201 }