125540Sdfr/*- 225540Sdfr * Copyright (c) 1997 Doug Rabson 325540Sdfr * All rights reserved. 425540Sdfr * 525540Sdfr * Redistribution and use in source and binary forms, with or without 625540Sdfr * modification, are permitted provided that the following conditions 725540Sdfr * are met: 825540Sdfr * 1. Redistributions of source code must retain the above copyright 925540Sdfr * notice, this list of conditions and the following disclaimer. 1025540Sdfr * 2. Redistributions in binary form must reproduce the above copyright 1125540Sdfr * notice, this list of conditions and the following disclaimer in the 1225540Sdfr * documentation and/or other materials provided with the distribution. 1325540Sdfr * 1425540Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1525540Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1625540Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1725540Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1825540Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1925540Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2025540Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2125540Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2225540Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2325540Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2425540Sdfr * SUCH DAMAGE. 2525540Sdfr */ 2625540Sdfr 27114589Sobrien#include <sys/cdefs.h> 28114589Sobrien__FBSDID("$FreeBSD$"); 2932270Scharnier 30156087Swkoszek#include <sys/param.h> 31156087Swkoszek#include <sys/linker.h> 32156087Swkoszek 3330573Sjmg#include <err.h> 3425540Sdfr#include <stdio.h> 3530573Sjmg#include <stdlib.h> 36156091Swkoszek#include <sysexits.h> 3725540Sdfr#include <unistd.h> 3825540Sdfr 3930627Sjmgstatic void 4030627Sjmgusage(void) 4125540Sdfr{ 42156091Swkoszek fprintf(stderr, "usage: kldunload [-fv] -i id ...\n"); 43156091Swkoszek fprintf(stderr, " kldunload [-fv] [-n] name ...\n"); 44156091Swkoszek exit(EX_USAGE); 4525540Sdfr} 4625540Sdfr 47156091Swkoszek#define OPT_NULL 0x00 48156091Swkoszek#define OPT_ID 0x01 49156091Swkoszek#define OPT_VERBOSE 0x02 50156091Swkoszek#define OPT_FORCE 0x04 51156091Swkoszek 5230627Sjmgint 5330627Sjmgmain(int argc, char** argv) 5425540Sdfr{ 55156087Swkoszek struct kld_file_stat stat; 56156091Swkoszek int c, fileid, force, opt; 57156091Swkoszek char *filename; 5825540Sdfr 59156091Swkoszek filename = NULL; 60156091Swkoszek opt = OPT_NULL; 61156091Swkoszek 62156091Swkoszek while ((c = getopt(argc, argv, "finv")) != -1) { 63156087Swkoszek switch (c) { 64156087Swkoszek case 'f': 65156091Swkoszek opt |= OPT_FORCE; 66156087Swkoszek break; 67156087Swkoszek case 'i': 68156091Swkoszek opt |= OPT_ID; 69156087Swkoszek break; 70156087Swkoszek case 'n': 71156091Swkoszek /* 72156091Swkoszek * XXX: For backward compatibility. Currently does 73156091Swkoszek * nothing 74156091Swkoszek */ 75156087Swkoszek break; 76156087Swkoszek case 'v': 77156091Swkoszek opt |= OPT_VERBOSE; 78156087Swkoszek break; 79156087Swkoszek default: 80156087Swkoszek usage(); 81156087Swkoszek } 8225540Sdfr } 8325540Sdfr 84156087Swkoszek argc -= optind; 85156087Swkoszek argv += optind; 8625540Sdfr 87156091Swkoszek if (argc == 0) 88156087Swkoszek usage(); 8925540Sdfr 90156091Swkoszek while ((filename = *argv++) != NULL) { 91156091Swkoszek if (opt & OPT_ID) { 92156091Swkoszek fileid = atoi(filename); 93156091Swkoszek if (fileid < 0) 94156091Swkoszek errx(EXIT_FAILURE, "Invalid ID %s", optarg); 95156091Swkoszek } else { 96156091Swkoszek if ((fileid = kldfind(filename)) < 0) 97156091Swkoszek errx(EXIT_FAILURE, "can't find file %s", 98156091Swkoszek filename); 99156091Swkoszek } 100156091Swkoszek if (opt & OPT_VERBOSE) { 101156091Swkoszek stat.version = sizeof(stat); 102156091Swkoszek if (kldstat(fileid, &stat) < 0) 103156091Swkoszek err(EXIT_FAILURE, "can't stat file"); 104156091Swkoszek (void) printf("Unloading %s, id=%d\n", stat.name, 105156091Swkoszek fileid); 106156091Swkoszek } 107156091Swkoszek if (opt & OPT_FORCE) 108156091Swkoszek force = LINKER_UNLOAD_FORCE; 109156091Swkoszek else 110156091Swkoszek force = LINKER_UNLOAD_NORMAL; 11125540Sdfr 112156091Swkoszek if (kldunloadf(fileid, force) < 0) 113156091Swkoszek err(EXIT_FAILURE, "can't unload file"); 114156087Swkoszek } 11525540Sdfr 116156091Swkoszek return (EXIT_SUCCESS); 11725540Sdfr} 118