1155804Sdes/*-
2211619Sdes * Copyright (c) 2006 Dag-Erling Co��dan Sm��rgrav
3155804Sdes * All rights reserved.
4155804Sdes *
5155804Sdes * Redistribution and use in source and binary forms, with or without
6155804Sdes * modification, are permitted provided that the following conditions
7155804Sdes * are met:
8155804Sdes * 1. Redistributions of source code must retain the above copyright
9155804Sdes *    notice, this list of conditions and the following disclaimer
10155804Sdes *    in this position and unchanged.
11155804Sdes * 2. Redistributions in binary form must reproduce the above copyright
12155804Sdes *    notice, this list of conditions and the following disclaimer in the
13155804Sdes *    documentation and/or other materials provided with the distribution.
14155804Sdes *
15155804Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16155804Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17155804Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18155804Sdes * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19155804Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20155804Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21155804Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22155804Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23155804Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24155804Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25155804Sdes * SUCH DAMAGE.
26155804Sdes *
27155804Sdes * $FreeBSD$
28155804Sdes */
29155804Sdes
30155804Sdes#include <sys/param.h>
31155804Sdes#include <sys/linker.h>
32155804Sdes#include <sys/module.h>
33155804Sdes
34155804Sdes#include <errno.h>
35158907Sdelphij#include <libutil.h>
36158907Sdelphij#include <string.h>
37155804Sdes
38155804Sdesint
39155804Sdeskld_isloaded(const char *name)
40155804Sdes{
41155804Sdes	struct kld_file_stat fstat;
42155804Sdes	struct module_stat mstat;
43155804Sdes	const char *ko;
44155804Sdes	int fid, mid;
45155804Sdes
46155804Sdes	for (fid = kldnext(0); fid > 0; fid = kldnext(fid)) {
47155804Sdes		fstat.version = sizeof(fstat);
48155804Sdes		if (kldstat(fid, &fstat) != 0)
49155804Sdes			continue;
50155804Sdes		/* check if the file name matches the supplied name */
51155804Sdes		if (strcmp(fstat.name, name) == 0)
52155804Sdes			return (1);
53155804Sdes		/* strip .ko and try again */
54155804Sdes		if ((ko = strstr(fstat.name, ".ko")) != NULL &&
55158907Sdelphij		    strlen(name) == (size_t)(ko - fstat.name) &&
56155804Sdes		    strncmp(fstat.name, name, ko - fstat.name) == 0)
57155804Sdes			return (1);
58155804Sdes		/* look for a matching module within the file */
59155804Sdes		for (mid = kldfirstmod(fid); mid > 0; mid = modfnext(mid)) {
60155804Sdes			mstat.version = sizeof(mstat);
61155804Sdes			if (modstat(mid, &mstat) != 0)
62155804Sdes				continue;
63155804Sdes			if (strcmp(mstat.name, name) == 0)
64155804Sdes				return (1);
65155804Sdes		}
66155804Sdes	}
67155804Sdes	return (0);
68155804Sdes}
69155804Sdes
70155804Sdesint
71155804Sdeskld_load(const char *name)
72155804Sdes{
73155804Sdes	if (kldload(name) == -1 && errno != EEXIST)
74155804Sdes		return (-1);
75155804Sdes	return (0);
76155804Sdes}
77