diff --git a/sbin/Makefile b/sbin/Makefile deleted file mode 100644 index 81022b520..000000000 --- a/sbin/Makefile +++ /dev/null @@ -1,72 +0,0 @@ -# $NetBSD: Makefile,v 1.127 2014/09/11 13:10:03 roy Exp $ -# @(#)Makefile 8.5 (Berkeley) 3/31/94 - -# Not ported: XNSrouted enpload scsiformat startslip -# Missing: icheck ncheck - -.include - -SUBDIR= \ - chown \ - fsck ifconfig init \ - mknod nologin \ - ping \ - reboot rcorder route \ - shutdown sysctl \ - -# support for various file systems -SUBDIR+= newfs_ext2fs fsck_ext2fs newfs_msdos newfs_udf newfs_v7fs -.if !defined(__MINIX) -SUBDIR+= newfs fsck_ffs fsdb dump restore clri tunefs resize_ffs -SUBDIR+= newfs_lfs fsck_lfs dump_lfs resize_lfs -SUBDIR+= newfs_msdos fsck_msdos -SUBDIR+= newfs_sysvbfs -SUBDIR+= newfs_udf -SUBDIR+= newfs_v7fs fsck_v7fs -SUBDIR+= mount_ados -SUBDIR+= mount_cd9660 -SUBDIR+= mount_chfs -SUBDIR+= mount_efs -SUBDIR+= mount_ext2fs -SUBDIR+= mount_fdesc -SUBDIR+= mount_filecore -SUBDIR+= mount_ffs -SUBDIR+= mount_hfs -SUBDIR+= mount_kernfs -SUBDIR+= mount_lfs -SUBDIR+= mount_msdos -SUBDIR+= mount_udf -SUBDIR+= mount_nfs -SUBDIR+= mount_nilfs -SUBDIR+= mount_ntfs -SUBDIR+= mount_null -SUBDIR+= mount_overlay -SUBDIR+= mount_portal -SUBDIR+= mount_procfs -SUBDIR+= mount_ptyfs -SUBDIR+= mount_puffs -SUBDIR+= mount_sysvbfs -SUBDIR+= mount_tmpfs -SUBDIR+= mount_umap -SUBDIR+= mount_union -SUBDIR+= mount_v7fs - -.if (${MKCRYPTO} != "no") -SUBDIR+= cgdconfig -.endif -.endif # !defined(__MINIX) - -.if (${USE_INET6} != "no") -SUBDIR+= ping6 -.endif - -.if !defined(__MINIX) -.if (${MKISCSI} != "no") -SUBDIR+= iscsictl iscsid -.endif - -# IPsec -SUBDIR+= setkey - -.endif # !defined(__MINIX) -.include diff --git a/sbin/Makefile.inc b/sbin/Makefile.inc deleted file mode 100644 index ece054b8f..000000000 --- a/sbin/Makefile.inc +++ /dev/null @@ -1,11 +0,0 @@ -# $NetBSD: Makefile.inc,v 1.22 2012/03/21 05:47:53 matt Exp $ -# @(#)Makefile.inc 8.1 (Berkeley) 6/8/93 - -.include # for MKDYNAMICROOT definition - -WARNS?= 5 -BINDIR?= /sbin - -.if (${MKDYNAMICROOT} == "no") -LDSTATIC?= -static -.endif diff --git a/sbin/ifconfig/Makefile.inc b/sbin/ifconfig/Makefile.inc deleted file mode 100644 index a6e4ce9f7..000000000 --- a/sbin/ifconfig/Makefile.inc +++ /dev/null @@ -1,23 +0,0 @@ -# $NetBSD: Makefile.inc,v 1.9 2012/10/31 10:17:34 msaitoh Exp $ - -# shared stuff with src/distrib/utils/x_ifconfig for install media. -# stuff not required by install media should be into Makefile. - -DPADD+=${LIBUTIL} -DPADD+=${LIBPROP} -LDADD+=-lutil -LDADD+=-lprop - -INCS+=af_inetany.h env.h extern.h media.h parse.h util.h -SRCS+= af_inet.c -SRCS+= af_inetany.c -#SRCS+= agr.c -SRCS+= env.c -SRCS+= ether.c -SRCS+= ieee80211.c -SRCS+= ifconfig.c -SRCS+= media.c -SRCS+= parse.c -SRCS+= tunnel.c -SRCS+= util.c -#SRCS+= vlan.c diff --git a/sbin/ifconfig/af_atalk.c b/sbin/ifconfig/af_atalk.c deleted file mode 100644 index 494b070c4..000000000 --- a/sbin/ifconfig/af_atalk.c +++ /dev/null @@ -1,249 +0,0 @@ -/* $NetBSD: af_atalk.c,v 1.19 2013/10/19 00:35:30 christos Exp $ */ - -/* - * Copyright (c) 1983, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#ifndef lint -__RCSID("$NetBSD: af_atalk.c,v 1.19 2013/10/19 00:35:30 christos Exp $"); -#endif /* not lint */ - -#include -#include -#include - -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "env.h" -#include "af_inetany.h" -#include "parse.h" -#include "extern.h" -#include "prog_ops.h" - -#ifndef satocsat -#define satocsat(__sa) ((const struct sockaddr_at *)(__sa)) -#endif - -static void at_status(prop_dictionary_t, prop_dictionary_t, bool); -static void at_commit_address(prop_dictionary_t, prop_dictionary_t); - -static void at_constructor(void) __attribute__((constructor)); - -static struct afswtch ataf = { - .af_name = "atalk", .af_af = AF_APPLETALK, .af_status = at_status, - .af_addr_commit = at_commit_address -}; -struct pinteger phase = PINTEGER_INITIALIZER1(&phase, "phase", - 1, 2, 10, NULL, "phase", &command_root.pb_parser); - -struct pstr parse_range = PSTR_INITIALIZER(&range, "range", NULL, "range", - &command_root.pb_parser); - -static const struct kwinst atalkkw[] = { - {.k_word = "phase", .k_nextparser = &phase.pi_parser} - , {.k_word = "range", .k_nextparser = &parse_range.ps_parser} -}; - -struct pkw atalk = PKW_INITIALIZER(&atalk, "AppleTalk", NULL, NULL, - atalkkw, __arraycount(atalkkw), NULL); - -static cmdloop_branch_t branch; - -static void -setatrange_impl(prop_dictionary_t env, prop_dictionary_t oenv, - struct netrange *nr) -{ - char range[24]; - u_short first = 123, last = 123; - - if (getargstr(env, "range", range, sizeof(range)) == -1) - return; - - if (sscanf(range, "%hu-%hu", &first, &last) != 2 || - first == 0 || last == 0 || first > last) - errx(EXIT_FAILURE, "%s: illegal net range: %u-%u", range, - first, last); - nr->nr_firstnet = htons(first); - nr->nr_lastnet = htons(last); -} - -static void -at_commit_address(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct ifreq ifr; - struct ifaliasreq ifra __attribute__((aligned(4))); - struct afparam atparam = { - .req = BUFPARAM(ifra) - , .dgreq = BUFPARAM(ifr) - , .name = { - {.buf = ifr.ifr_name, - .buflen = sizeof(ifr.ifr_name)} - , {.buf = ifra.ifra_name, - .buflen = sizeof(ifra.ifra_name)} - } - , .dgaddr = BUFPARAM(ifr.ifr_addr) - , .addr = BUFPARAM(ifra.ifra_addr) - , .dst = BUFPARAM(ifra.ifra_dstaddr) - , .brd = BUFPARAM(ifra.ifra_broadaddr) - , .mask = BUFPARAM(ifra.ifra_mask) - , .aifaddr = IFADDR_PARAM(SIOCAIFADDR) - , .difaddr = IFADDR_PARAM(SIOCDIFADDR) - , .gifaddr = IFADDR_PARAM(SIOCGIFADDR) - , .defmask = {.buf = NULL, .buflen = 0} - }; - struct netrange nr = {.nr_phase = 2}; /* AppleTalk net range */ - prop_data_t d, d0; - prop_dictionary_t ienv; - struct paddr_prefix *addr; - struct sockaddr_at *sat; - - if ((d0 = (prop_data_t)prop_dictionary_get(env, "address")) == NULL) - return; - - addr = prop_data_data(d0); - - sat = (struct sockaddr_at *)&addr->pfx_addr; - - (void)prop_dictionary_get_uint8(env, "phase", &nr.nr_phase); - /* Default range of one */ - nr.nr_firstnet = nr.nr_lastnet = sat->sat_addr.s_net; - setatrange_impl(env, oenv, &nr); - - if (ntohs(nr.nr_firstnet) > ntohs(sat->sat_addr.s_net) || - ntohs(nr.nr_lastnet) < ntohs(sat->sat_addr.s_net)) - errx(EXIT_FAILURE, "AppleTalk address is not in range"); - memcpy(&sat->sat_zero, &nr, sizeof(nr)); - - /* Copy the new address to a temporary input environment */ - - d = prop_data_create_data_nocopy(addr, paddr_prefix_size(addr)); - ienv = prop_dictionary_copy_mutable(env); - - if (d == NULL) - err(EXIT_FAILURE, "%s: prop_data_create_data", __func__); - if (ienv == NULL) - err(EXIT_FAILURE, "%s: prop_dictionary_copy_mutable", __func__); - - if (!prop_dictionary_set(ienv, "address", (prop_object_t)d)) - err(EXIT_FAILURE, "%s: prop_dictionary_set", __func__); - - /* copy to output environment for good measure */ - if (!prop_dictionary_set(oenv, "address", (prop_object_t)d)) - err(EXIT_FAILURE, "%s: prop_dictionary_set", __func__); - - prop_object_release((prop_object_t)d); - - memset(&ifr, 0, sizeof(ifr)); - memset(&ifra, 0, sizeof(ifra)); - commit_address(ienv, oenv, &atparam); - - /* release temporary input environment */ - prop_object_release((prop_object_t)ienv); -} - -static void -sat_print1(const char *prefix, const struct sockaddr *sa) -{ - char buf[40]; - - (void)getnameinfo(sa, sa->sa_len, buf, sizeof(buf), NULL, 0, 0); - - printf("%s%s", prefix, buf); -} - -static void -at_status(prop_dictionary_t env, prop_dictionary_t oenv, bool force) -{ - struct sockaddr_at *sat; - struct ifreq ifr; - int s; - const char *ifname; - unsigned short flags; - - if ((s = getsock(AF_APPLETALK)) == -1) { - if (errno == EAFNOSUPPORT) - return; - err(EXIT_FAILURE, "getsock"); - } - if ((ifname = getifinfo(env, oenv, &flags)) == NULL) - err(EXIT_FAILURE, "%s: getifinfo", __func__); - - memset(&ifr, 0, sizeof(ifr)); - estrlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - ifr.ifr_addr.sa_family = AF_APPLETALK; - if (prog_ioctl(s, SIOCGIFADDR, &ifr) != -1) - ; - else if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) { - if (!force) - return; - memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr)); - } else - warn("SIOCGIFADDR"); - sat = (struct sockaddr_at *)&ifr.ifr_addr; - - sat_print1("\tatalk ", &ifr.ifr_addr); - - if (flags & IFF_POINTOPOINT) { - estrlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (prog_ioctl(s, SIOCGIFDSTADDR, &ifr) == -1) { - if (errno == EADDRNOTAVAIL) - memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr)); - else - warn("SIOCGIFDSTADDR"); - } - sat_print1(" --> ", &ifr.ifr_dstaddr); - } - if (flags & IFF_BROADCAST) { - /* note RTAX_BRD overlap with IFF_POINTOPOINT */ - /* note Appletalk broadcast is fixed. */ - printf(" broadcast %u.%u", ntohs(sat->sat_addr.s_net), - ATADDR_BCAST); - } - printf("\n"); -} - -static void -at_constructor(void) -{ - register_family(&ataf); - cmdloop_branch_init(&branch, &atalk.pk_parser); - register_cmdloop_branch(&branch); -} diff --git a/sbin/ifconfig/af_inet.c b/sbin/ifconfig/af_inet.c deleted file mode 100644 index f4a00c764..000000000 --- a/sbin/ifconfig/af_inet.c +++ /dev/null @@ -1,247 +0,0 @@ -/* $NetBSD: af_inet.c,v 1.17 2015/05/12 14:05:29 roy Exp $ */ - -/* - * Copyright (c) 1983, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#ifndef lint -__RCSID("$NetBSD: af_inet.c,v 1.17 2015/05/12 14:05:29 roy Exp $"); -#endif /* not lint */ - -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "env.h" -#include "extern.h" -#include "af_inetany.h" -#include "prog_ops.h" - -static void in_constructor(void) __attribute__((constructor)); -static void in_status(prop_dictionary_t, prop_dictionary_t, bool); -static void in_commit_address(prop_dictionary_t, prop_dictionary_t); -static bool in_addr_tentative(struct ifaddrs *ifa); -static void in_alias(const char *, prop_dictionary_t, prop_dictionary_t, - struct in_aliasreq *); - -static struct afswtch af = { - .af_name = "inet", .af_af = AF_INET, .af_status = in_status, - .af_addr_commit = in_commit_address, - .af_addr_tentative = in_addr_tentative -}; - -static void -in_alias(const char *ifname, prop_dictionary_t env, prop_dictionary_t oenv, - struct in_aliasreq *creq) -{ - struct ifreq ifr; - bool alias; - int s; - unsigned short flags; - struct in_aliasreq in_addreq; - const struct sockaddr_in * const asin = &in_addreq.ifra_addr; - const struct sockaddr_in * const dsin = &in_addreq.ifra_dstaddr; - const struct sockaddr_in * const bsin = &in_addreq.ifra_broadaddr; - char hbuf[NI_MAXHOST]; - const int niflag = Nflag ? 0 : NI_NUMERICHOST; - - if (lflag) - return; - - alias = true; - - /* Get the non-alias address for this interface. */ - if ((s = getsock(AF_INET)) == -1) { - if (errno == EAFNOSUPPORT) - return; - err(EXIT_FAILURE, "socket"); - } - memset(&ifr, 0, sizeof(ifr)); - estrlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (prog_ioctl(s, SIOCGIFADDR, &ifr) == -1) { - if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) - return; - warn("SIOCGIFADDR"); - } - /* If creq and ifr are the same address, this is not an alias. */ - if (memcmp(&ifr.ifr_addr, &creq->ifra_addr, sizeof(ifr.ifr_addr)) == 0) - alias = false; - in_addreq = *creq; - if (prog_ioctl(s, SIOCGIFALIAS, &in_addreq) == -1) { - if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) { - return; - } else - warn("SIOCGIFALIAS"); - } - - if (getnameinfo((const struct sockaddr *)asin, asin->sin_len, - hbuf, sizeof(hbuf), NULL, 0, niflag)) - strlcpy(hbuf, "", sizeof(hbuf)); /* some message? */ - printf("\tinet %s%s", alias ? "alias " : "", hbuf); - - if (getifflags(env, oenv, &flags) == -1) - err(EXIT_FAILURE, "%s: getifflags", __func__); - - if (flags & IFF_POINTOPOINT) { - if (getnameinfo((const struct sockaddr *)dsin, dsin->sin_len, - hbuf, sizeof(hbuf), NULL, 0, niflag)) - strlcpy(hbuf, "", sizeof(hbuf)); /* some message? */ - printf(" -> %s", hbuf); - } - - printf(" netmask 0x%x", ntohl(in_addreq.ifra_mask.sin_addr.s_addr)); - - if (flags & IFF_BROADCAST) { - if (getnameinfo((const struct sockaddr *)bsin, bsin->sin_len, - hbuf, sizeof(hbuf), NULL, 0, niflag)) - strlcpy(hbuf, "", sizeof(hbuf)); /* some message? */ - printf(" broadcast %s", hbuf); - } - -#ifdef IN_IFF_TENTATIVE - memcpy(&ifr.ifr_addr, &creq->ifra_addr, creq->ifra_addr.sin_len); - if (prog_ioctl(s, SIOCGIFAFLAG_IN, &ifr) == -1) { - if (errno != EADDRNOTAVAIL) - warn("SIOCGIFAFLAG_IN"); - } else { - if (ifr.ifr_addrflags & IN_IFF_TENTATIVE) - printf(" tentative"); - if (ifr.ifr_addrflags & IN_IFF_DUPLICATED) - printf(" duplicated"); - if (ifr.ifr_addrflags & IN_IFF_DETACHED) - printf(" detached"); - } -#endif -} - -static void -in_status(prop_dictionary_t env, prop_dictionary_t oenv, bool force) -{ - struct ifaddrs *ifap, *ifa; - struct in_aliasreq ifra; - bool printprefs = false; - const char *ifname; - - if ((ifname = getifname(env)) == NULL) - err(EXIT_FAILURE, "%s: getifname", __func__); - - if (getifaddrs(&ifap) != 0) - err(EXIT_FAILURE, "getifaddrs"); - - printprefs = ifa_any_preferences(ifname, ifap, AF_INET); - - for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { - if (strcmp(ifname, ifa->ifa_name) != 0) - continue; - if (ifa->ifa_addr->sa_family != AF_INET) - continue; - if (sizeof(ifra.ifra_addr) < ifa->ifa_addr->sa_len) - continue; - - memset(&ifra, 0, sizeof(ifra)); - estrlcpy(ifra.ifra_name, ifa->ifa_name, sizeof(ifra.ifra_name)); - memcpy(&ifra.ifra_addr, ifa->ifa_addr, ifa->ifa_addr->sa_len); - in_alias(ifa->ifa_name, env, oenv, &ifra); - if (printprefs) - ifa_print_preference(ifa->ifa_name, ifa->ifa_addr); - printf("\n"); - } - freeifaddrs(ifap); -} - -static void -in_commit_address(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct ifreq in_ifr; - struct in_aliasreq in_ifra; - struct afparam inparam = { - .req = BUFPARAM(in_ifra) - , .dgreq = BUFPARAM(in_ifr) - , .name = { - {.buf = in_ifr.ifr_name, - .buflen = sizeof(in_ifr.ifr_name)} - , {.buf = in_ifra.ifra_name, - .buflen = sizeof(in_ifra.ifra_name)} - } - , .dgaddr = BUFPARAM(in_ifr.ifr_addr) - , .addr = BUFPARAM(in_ifra.ifra_addr) - , .dst = BUFPARAM(in_ifra.ifra_dstaddr) - , .brd = BUFPARAM(in_ifra.ifra_broadaddr) - , .mask = BUFPARAM(in_ifra.ifra_mask) - , .aifaddr = IFADDR_PARAM(SIOCAIFADDR) - , .difaddr = IFADDR_PARAM(SIOCDIFADDR) - , .gifaddr = IFADDR_PARAM(SIOCGIFADDR) - , .defmask = {.buf = NULL, .buflen = 0} - }; - memset(&in_ifr, 0, sizeof(in_ifr)); - memset(&in_ifra, 0, sizeof(in_ifra)); - commit_address(env, oenv, &inparam); -} - -static bool -in_addr_tentative(struct ifaddrs *ifa) -{ -#ifdef IN_IFF_TENTATIVE - int s; - struct ifreq ifr; - - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, ifa->ifa_name, sizeof(ifr.ifr_name)); - ifr.ifr_addr = *ifa->ifa_addr; - if ((s = getsock(AF_INET)) == -1) - err(EXIT_FAILURE, "%s: getsock", __func__); - if (prog_ioctl(s, SIOCGIFAFLAG_IN, &ifr) == -1) - err(EXIT_FAILURE, "SIOCGIFAFLAG_IN"); - return ifr.ifr_addrflags & IN_IFF_TENTATIVE ? true : false; -#else - return false; -#endif -} - -static void -in_constructor(void) -{ - register_family(&af); -} diff --git a/sbin/ifconfig/af_inet6.c b/sbin/ifconfig/af_inet6.c deleted file mode 100644 index e5474105a..000000000 --- a/sbin/ifconfig/af_inet6.c +++ /dev/null @@ -1,516 +0,0 @@ -/* $NetBSD: af_inet6.c,v 1.33 2015/05/12 14:05:29 roy Exp $ */ - -/* - * Copyright (c) 1983, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#ifndef lint -__RCSID("$NetBSD: af_inet6.c,v 1.33 2015/05/12 14:05:29 roy Exp $"); -#endif /* not lint */ - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "env.h" -#include "extern.h" -#include "parse.h" -#include "extern.h" -#include "af_inetany.h" -#include "prog_ops.h" - -static void in6_constructor(void) __attribute__((constructor)); -static void in6_alias(const char *, prop_dictionary_t, prop_dictionary_t, - struct in6_ifreq *); -static void in6_commit_address(prop_dictionary_t, prop_dictionary_t); - -static int setia6eui64_impl(prop_dictionary_t, struct in6_aliasreq *); -static int setia6flags_impl(prop_dictionary_t, struct in6_aliasreq *); -static int setia6pltime_impl(prop_dictionary_t, struct in6_aliasreq *); -static int setia6vltime_impl(prop_dictionary_t, struct in6_aliasreq *); - -static int setia6lifetime(prop_dictionary_t, int64_t, time_t *, uint32_t *); - -static void in6_status(prop_dictionary_t, prop_dictionary_t, bool); -static bool in6_addr_tentative(struct ifaddrs *ifa); - -static struct usage_func usage; -static cmdloop_branch_t branch[2]; - -static const struct kwinst ia6flagskw[] = { - IFKW("anycast", IN6_IFF_ANYCAST) - , IFKW("deprecated", IN6_IFF_DEPRECATED) -}; - -static struct pinteger parse_pltime = PINTEGER_INITIALIZER(&parse_pltime, - "pltime", 0, NULL, "pltime", &command_root.pb_parser); - -static struct pinteger parse_vltime = PINTEGER_INITIALIZER(&parse_vltime, - "vltime", 0, NULL, "vltime", &command_root.pb_parser); - -static const struct kwinst inet6kw[] = { - {.k_word = "pltime", .k_nextparser = &parse_pltime.pi_parser} - , {.k_word = "vltime", .k_nextparser = &parse_vltime.pi_parser} - , {.k_word = "eui64", .k_key = "eui64", .k_type = KW_T_BOOL, - .k_bool = true, .k_nextparser = &command_root.pb_parser} -}; - -struct pkw ia6flags = PKW_INITIALIZER(&ia6flags, "ia6flags", NULL, - "ia6flag", ia6flagskw, __arraycount(ia6flagskw), &command_root.pb_parser); -struct pkw inet6 = PKW_INITIALIZER(&inet6, "IPv6 keywords", NULL, - NULL, inet6kw, __arraycount(inet6kw), NULL); - -static struct afswtch in6af = { - .af_name = "inet6", .af_af = AF_INET6, .af_status = in6_status, - .af_addr_commit = in6_commit_address, - .af_addr_tentative = in6_addr_tentative -}; - -static int -prefix(void *val, int size) -{ - u_char *pname = (u_char *)val; - int byte, bit, plen = 0; - - for (byte = 0; byte < size; byte++, plen += 8) - if (pname[byte] != 0xff) - break; - if (byte == size) - return (plen); - for (bit = 7; bit != 0; bit--, plen++) - if (!(pname[byte] & (1 << bit))) - break; - for (; bit != 0; bit--) - if (pname[byte] & (1 << bit)) - return(0); - byte++; - for (; byte < size; byte++) - if (pname[byte]) - return(0); - return (plen); -} - -int -setia6flags_impl(prop_dictionary_t env, struct in6_aliasreq *ifra) -{ - int64_t ia6flag; - - if (!prop_dictionary_get_int64(env, "ia6flag", &ia6flag)) { - errno = ENOENT; - return -1; - } - - if (ia6flag < 0) { - ia6flag = -ia6flag; - ifra->ifra_flags &= ~ia6flag; - } else - ifra->ifra_flags |= ia6flag; - return 0; -} - -int -setia6pltime_impl(prop_dictionary_t env, struct in6_aliasreq *ifra) -{ - int64_t pltime; - - if (!prop_dictionary_get_int64(env, "pltime", &pltime)) { - errno = ENOENT; - return -1; - } - - return setia6lifetime(env, pltime, - &ifra->ifra_lifetime.ia6t_preferred, - &ifra->ifra_lifetime.ia6t_pltime); -} - -int -setia6vltime_impl(prop_dictionary_t env, struct in6_aliasreq *ifra) -{ - int64_t vltime; - - if (!prop_dictionary_get_int64(env, "vltime", &vltime)) { - errno = ENOENT; - return -1; - } - - return setia6lifetime(env, vltime, - &ifra->ifra_lifetime.ia6t_expire, - &ifra->ifra_lifetime.ia6t_vltime); -} - -static int -setia6lifetime(prop_dictionary_t env, int64_t val, time_t *timep, - uint32_t *ivalp) -{ - time_t t; - int af; - - if ((af = getaf(env)) == -1 || af != AF_INET6) { - errx(EXIT_FAILURE, - "inet6 address lifetime not allowed for the AF"); - } - - t = time(NULL); - *timep = t + val; - *ivalp = val; - return 0; -} - -int -setia6eui64_impl(prop_dictionary_t env, struct in6_aliasreq *ifra) -{ - char buf[2][80]; - struct ifaddrs *ifap, *ifa; - const struct sockaddr_in6 *sin6 = NULL; - const struct in6_addr *lladdr = NULL; - struct in6_addr *in6; - const char *ifname; - bool doit = false; - int af; - - if (!prop_dictionary_get_bool(env, "eui64", &doit) || !doit) { - errno = ENOENT; - return -1; - } - - if ((ifname = getifname(env)) == NULL) - return -1; - - af = getaf(env); - if (af != AF_INET6) { - errx(EXIT_FAILURE, - "eui64 address modifier not allowed for the AF"); - } - in6 = &ifra->ifra_addr.sin6_addr; - if (memcmp(&in6addr_any.s6_addr[8], &in6->s6_addr[8], 8) != 0) { - union { - struct sockaddr_in6 sin6; - struct sockaddr sa; - } any = {.sin6 = {.sin6_family = AF_INET6}}; - memcpy(&any.sin6.sin6_addr, &in6addr_any, - sizeof(any.sin6.sin6_addr)); - (void)sockaddr_snprintf(buf[0], sizeof(buf[0]), "%a%%S", - &any.sa); - (void)sockaddr_snprintf(buf[1], sizeof(buf[1]), "%a%%S", - (const struct sockaddr *)&ifra->ifra_addr); - errx(EXIT_FAILURE, "interface index is already filled, %s | %s", - buf[0], buf[1]); - } - if (getifaddrs(&ifap) != 0) - err(EXIT_FAILURE, "getifaddrs"); - for (ifa = ifap; ifa; ifa = ifa->ifa_next) { - if (ifa->ifa_addr->sa_family == AF_INET6 && - strcmp(ifa->ifa_name, ifname) == 0) { - sin6 = (const struct sockaddr_in6 *)ifa->ifa_addr; - if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { - lladdr = &sin6->sin6_addr; - break; - } - } - } - if (lladdr == NULL) - errx(EXIT_FAILURE, "could not determine link local address"); - - memcpy(&in6->s6_addr[8], &lladdr->s6_addr[8], 8); - - freeifaddrs(ifap); - return 0; -} - -/* XXX not really an alias */ -void -in6_alias(const char *ifname, prop_dictionary_t env, prop_dictionary_t oenv, - struct in6_ifreq *creq) -{ - struct in6_ifreq ifr6; - struct sockaddr_in6 *sin6; - char hbuf[NI_MAXHOST]; - u_int32_t scopeid; - int s; - const int niflag = Nflag ? 0 : NI_NUMERICHOST; - unsigned short flags; - - /* Get the non-alias address for this interface. */ - if ((s = getsock(AF_INET6)) == -1) { - if (errno == EAFNOSUPPORT) - return; - err(EXIT_FAILURE, "socket"); - } - - sin6 = &creq->ifr_addr; - - inet6_getscopeid(sin6, INET6_IS_ADDR_LINKLOCAL); - scopeid = sin6->sin6_scope_id; - if (getnameinfo((const struct sockaddr *)sin6, sin6->sin6_len, - hbuf, sizeof(hbuf), NULL, 0, niflag)) - strlcpy(hbuf, "", sizeof(hbuf)); /* some message? */ - printf("\tinet6 %s", hbuf); - - if (getifflags(env, oenv, &flags) == -1) - err(EXIT_FAILURE, "%s: getifflags", __func__); - - if (flags & IFF_POINTOPOINT) { - ifr6 = *creq; - if (prog_ioctl(s, SIOCGIFDSTADDR_IN6, &ifr6) == -1) { - if (errno != EADDRNOTAVAIL) - warn("SIOCGIFDSTADDR_IN6"); - memset(&ifr6.ifr_addr, 0, sizeof(ifr6.ifr_addr)); - ifr6.ifr_addr.sin6_family = AF_INET6; - ifr6.ifr_addr.sin6_len = sizeof(struct sockaddr_in6); - } - sin6 = &ifr6.ifr_addr; - inet6_getscopeid(sin6, INET6_IS_ADDR_LINKLOCAL); - hbuf[0] = '\0'; - if (getnameinfo((struct sockaddr *)sin6, sin6->sin6_len, - hbuf, sizeof(hbuf), NULL, 0, niflag)) - strlcpy(hbuf, "", sizeof(hbuf)); /* some message? */ - printf(" -> %s", hbuf); - } - - ifr6 = *creq; - if (prog_ioctl(s, SIOCGIFNETMASK_IN6, &ifr6) == -1) { - if (errno != EADDRNOTAVAIL) - warn("SIOCGIFNETMASK_IN6"); - } else { - sin6 = &ifr6.ifr_addr; - printf(" prefixlen %d", prefix(&sin6->sin6_addr, - sizeof(struct in6_addr))); - } - - ifr6 = *creq; - if (prog_ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) == -1) { - if (errno != EADDRNOTAVAIL) - warn("SIOCGIFAFLAG_IN6"); - } else { - if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_ANYCAST) - printf(" anycast"); - if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_TENTATIVE) - printf(" tentative"); - if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DUPLICATED) - printf(" duplicated"); - if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DETACHED) - printf(" detached"); - if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DEPRECATED) - printf(" deprecated"); - if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_AUTOCONF) - printf(" autoconf"); - if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_TEMPORARY) - printf(" temporary"); - } - - if (scopeid) - printf(" scopeid 0x%x", scopeid); - - if (get_flag('L')) { - struct in6_addrlifetime *lifetime; - ifr6 = *creq; - lifetime = &ifr6.ifr_ifru.ifru_lifetime; - if (prog_ioctl(s, SIOCGIFALIFETIME_IN6, &ifr6) == -1) { - if (errno != EADDRNOTAVAIL) - warn("SIOCGIFALIFETIME_IN6"); - } else if (lifetime->ia6t_preferred || lifetime->ia6t_expire) { - time_t t = time(NULL); - printf(" pltime "); - if (lifetime->ia6t_preferred) { - printf("%lu", - (unsigned long)(lifetime->ia6t_preferred - - MIN(t, lifetime->ia6t_preferred))); - } else - printf("infty"); - - printf(" vltime "); - if (lifetime->ia6t_expire) { - printf("%lu", - (unsigned long)(lifetime->ia6t_expire - - MIN(t, lifetime->ia6t_expire))); - } else - printf("infty"); - } - } -} - -static void -in6_status(prop_dictionary_t env, prop_dictionary_t oenv, bool force) -{ - struct ifaddrs *ifap, *ifa; - struct in6_ifreq ifr; - const char *ifname; - bool printprefs = false; - - if ((ifname = getifname(env)) == NULL) - err(EXIT_FAILURE, "%s: getifname", __func__); - - if (getifaddrs(&ifap) != 0) - err(EXIT_FAILURE, "getifaddrs"); - printprefs = ifa_any_preferences(ifname, ifap, AF_INET6); - for (ifa = ifap; ifa; ifa = ifa->ifa_next) { - if (strcmp(ifname, ifa->ifa_name) != 0) - continue; - if (ifa->ifa_addr->sa_family != AF_INET6) - continue; - if (sizeof(ifr.ifr_addr) < ifa->ifa_addr->sa_len) - continue; - - memset(&ifr, 0, sizeof(ifr)); - estrlcpy(ifr.ifr_name, ifa->ifa_name, sizeof(ifr.ifr_name)); - memcpy(&ifr.ifr_addr, ifa->ifa_addr, ifa->ifa_addr->sa_len); - in6_alias(ifname, env, oenv, &ifr); - if (printprefs) - ifa_print_preference(ifa->ifa_name, ifa->ifa_addr); - printf("\n"); - } - freeifaddrs(ifap); -} - -static int -in6_pre_aifaddr(prop_dictionary_t env, const struct afparam *param) -{ - struct in6_aliasreq *ifra = param->req.buf; - - setia6eui64_impl(env, ifra); - setia6vltime_impl(env, ifra); - setia6pltime_impl(env, ifra); - setia6flags_impl(env, ifra); - inet6_putscopeid(&ifra->ifra_addr, INET6_IS_ADDR_LINKLOCAL); - inet6_putscopeid(&ifra->ifra_dstaddr, INET6_IS_ADDR_LINKLOCAL); - - return 0; -} - -static void -in6_commit_address(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct in6_ifreq in6_ifr = { - .ifr_addr = { - .sin6_family = AF_INET6, - .sin6_len = sizeof(in6_ifr.ifr_addr), - .sin6_addr = { - .s6_addr = - {0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff} - } - } - }; - static struct sockaddr_in6 in6_defmask = { - .sin6_family = AF_INET6, - .sin6_len = sizeof(in6_defmask), - .sin6_addr = { - .s6_addr = {0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff} - } - }; - - struct in6_aliasreq in6_ifra = { - .ifra_prefixmask = { - .sin6_family = AF_INET6, - .sin6_len = sizeof(in6_ifra.ifra_prefixmask), - .sin6_addr = { - .s6_addr = - {0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff}}}, - .ifra_lifetime = { - .ia6t_pltime = ND6_INFINITE_LIFETIME - , .ia6t_vltime = ND6_INFINITE_LIFETIME - } - }; - struct afparam in6param = { - .req = BUFPARAM(in6_ifra) - , .dgreq = BUFPARAM(in6_ifr) - , .name = { - {.buf = in6_ifr.ifr_name, - .buflen = sizeof(in6_ifr.ifr_name)}, - {.buf = in6_ifra.ifra_name, - .buflen = sizeof(in6_ifra.ifra_name)} - } - , .dgaddr = BUFPARAM(in6_ifr.ifr_addr) - , .addr = BUFPARAM(in6_ifra.ifra_addr) - , .dst = BUFPARAM(in6_ifra.ifra_dstaddr) - , .brd = BUFPARAM(in6_ifra.ifra_broadaddr) - , .mask = BUFPARAM(in6_ifra.ifra_prefixmask) - , .aifaddr = IFADDR_PARAM(SIOCAIFADDR_IN6) - , .difaddr = IFADDR_PARAM(SIOCDIFADDR_IN6) - , .gifaddr = IFADDR_PARAM(SIOCGIFADDR_IN6) - , .defmask = BUFPARAM(in6_defmask) - , .pre_aifaddr = in6_pre_aifaddr - }; - commit_address(env, oenv, &in6param); -} - -static bool -in6_addr_tentative(struct ifaddrs *ifa) -{ - int s; - struct in6_ifreq ifr; - - if ((s = getsock(AF_INET6)) == -1) - err(EXIT_FAILURE, "%s: getsock", __func__); - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, ifa->ifa_name, sizeof(ifr.ifr_name)); - ifr.ifr_addr = *(struct sockaddr_in6 *)ifa->ifa_addr; - if (prog_ioctl(s, SIOCGIFAFLAG_IN6, &ifr) == -1) - err(EXIT_FAILURE, "SIOCGIFAFLAG_IN6"); - return ifr.ifr_ifru.ifru_flags6 & IN6_IFF_TENTATIVE ? true : false; -} - -static void -in6_usage(prop_dictionary_t env) -{ - fprintf(stderr, - "\t[ anycast | -anycast ] [ deprecated | -deprecated ]\n" - "\t[ pltime n ] [ vltime n ] " - "[ eui64 ]\n"); -} - -static void -in6_constructor(void) -{ - if (register_flag('L') != 0) - err(EXIT_FAILURE, __func__); - register_family(&in6af); - usage_func_init(&usage, in6_usage); - register_usage(&usage); - cmdloop_branch_init(&branch[0], &ia6flags.pk_parser); - cmdloop_branch_init(&branch[1], &inet6.pk_parser); - register_cmdloop_branch(&branch[0]); - register_cmdloop_branch(&branch[1]); -} diff --git a/sbin/ifconfig/af_inetany.h b/sbin/ifconfig/af_inetany.h deleted file mode 100644 index a040ea739..000000000 --- a/sbin/ifconfig/af_inetany.h +++ /dev/null @@ -1,59 +0,0 @@ -/* $NetBSD: af_inetany.h,v 1.4 2008/07/02 07:44:14 dyoung Exp $ */ - -/*- - * Copyright (c) 2008 David Young. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _IFCONFIG_AF_INETANY_H -#define _IFCONFIG_AF_INETANY_H - -#include -#include - -#define IFADDR_PARAM(__arg) {.cmd = (__arg), .desc = #__arg} -#define BUFPARAM(__arg) {.buf = &(__arg), .buflen = sizeof(__arg)} - -struct apbuf { - void *buf; - size_t buflen; -}; - -struct afparam { - struct { - char *buf; - size_t buflen; - } name[2]; - struct apbuf dgaddr, addr, brd, dst, mask, req, dgreq, defmask, - pre_aifaddr_arg; - struct { - unsigned long cmd; - const char *desc; - } aifaddr, difaddr, gifaddr; - int (*pre_aifaddr)(prop_dictionary_t, const struct afparam *); -}; - -void commit_address(prop_dictionary_t, prop_dictionary_t, - const struct afparam *); - -#endif /* _IFCONFIG_AF_INETANY_H */ diff --git a/sbin/ifconfig/af_link.c b/sbin/ifconfig/af_link.c deleted file mode 100644 index 18e0368a0..000000000 --- a/sbin/ifconfig/af_link.c +++ /dev/null @@ -1,132 +0,0 @@ -/* $NetBSD: af_link.c,v 1.7 2014/01/19 22:31:13 matt Exp $ */ - -/*- - * Copyright (c) 2008 David Young. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#ifndef lint -__RCSID("$NetBSD: af_link.c,v 1.7 2014/01/19 22:31:13 matt Exp $"); -#endif /* not lint */ - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "env.h" -#include "extern.h" -#include "af_inetany.h" - -static void link_status(prop_dictionary_t, prop_dictionary_t, bool); -static void link_commit_address(prop_dictionary_t, prop_dictionary_t); - -static const struct kwinst linkkw[] = { - {.k_word = "active", .k_key = "active", .k_type = KW_T_BOOL, - .k_bool = true, .k_nextparser = &command_root.pb_parser} -}; - -struct pkw link_pkw = PKW_INITIALIZER(&link_pkw, "link", NULL, NULL, - linkkw, __arraycount(linkkw), NULL); - -static struct afswtch af = { - .af_name = "link", .af_af = AF_LINK, .af_status = link_status, - .af_addr_commit = link_commit_address -}; - -static cmdloop_branch_t branch; - -static void link_constructor(void) __attribute__((constructor)); - -static void -link_status(prop_dictionary_t env, prop_dictionary_t oenv, bool force) -{ - print_link_addresses(env, false); -} - -static int -link_pre_aifaddr(prop_dictionary_t env, const struct afparam *param) -{ - bool active; - struct if_laddrreq *iflr = param->req.buf; - - if (prop_dictionary_get_bool(env, "active", &active) && active) - iflr->flags |= IFLR_ACTIVE; - - return 0; -} - -static void -link_commit_address(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct if_laddrreq dgreq = { - .addr = { - .ss_family = AF_LINK, - .ss_len = sizeof(dgreq.addr), - }, - }; - struct if_laddrreq req = { - .addr = { - .ss_family = AF_LINK, - .ss_len = sizeof(req.addr), - } - }; - struct afparam linkparam = { - .req = BUFPARAM(req) - , .dgreq = BUFPARAM(dgreq) - , .name = { - {.buf = dgreq.iflr_name, - .buflen = sizeof(dgreq.iflr_name)}, - {.buf = req.iflr_name, - .buflen = sizeof(req.iflr_name)} - } - , .dgaddr = BUFPARAM(dgreq.addr) - , .addr = BUFPARAM(req.addr) - , .aifaddr = IFADDR_PARAM(SIOCALIFADDR) - , .difaddr = IFADDR_PARAM(SIOCDLIFADDR) - , .gifaddr = IFADDR_PARAM(0) - , .pre_aifaddr = link_pre_aifaddr - }; - commit_address(env, oenv, &linkparam); -} - -static void -link_constructor(void) -{ - register_family(&af); - cmdloop_branch_init(&branch, &link_pkw.pk_parser); - register_cmdloop_branch(&branch); -} diff --git a/sbin/ifconfig/env.c b/sbin/ifconfig/env.c deleted file mode 100644 index 6d5c690a4..000000000 --- a/sbin/ifconfig/env.c +++ /dev/null @@ -1,180 +0,0 @@ -/* $NetBSD: env.c,v 1.9 2013/02/07 13:20:51 apb Exp $ */ - -/*- - * Copyright (c) 2008 David Young. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#ifndef lint -__RCSID("$NetBSD: env.c,v 1.9 2013/02/07 13:20:51 apb Exp $"); -#endif /* not lint */ - -#include -#include -#include -#include - -#include -#include -#include - -#include "env.h" -#include "util.h" -#include "prog_ops.h" - -prop_dictionary_t -prop_dictionary_augment(prop_dictionary_t bottom, prop_dictionary_t top) -{ - prop_object_iterator_t i; - prop_dictionary_t d; - prop_object_t ko, o; - prop_dictionary_keysym_t k; - const char *key; - - d = prop_dictionary_copy_mutable(bottom); - if (d == NULL) - return NULL; - - i = prop_dictionary_iterator(top); - - while (i != NULL && (ko = prop_object_iterator_next(i)) != NULL) { - k = (prop_dictionary_keysym_t)ko; - key = prop_dictionary_keysym_cstring_nocopy(k); - o = prop_dictionary_get_keysym(top, k); - if (o == NULL || !prop_dictionary_set(d, key, o)) { - prop_object_release((prop_object_t)d); - d = NULL; - break; - } - } - if (i != NULL) - prop_object_iterator_release(i); - if (d != NULL) - prop_dictionary_make_immutable(d); - return d; -} - -int -getifflags(prop_dictionary_t env, prop_dictionary_t oenv, - unsigned short *flagsp) -{ - struct ifreq ifr; - const char *ifname; - uint64_t ifflags; - int s; - - if (prop_dictionary_get_uint64(env, "ifflags", &ifflags)) { - *flagsp = (unsigned short)ifflags; - return 0; - } - - if ((s = getsock(AF_UNSPEC)) == -1) - return -1; - - if ((ifname = getifname(env)) == NULL) - return -1; - - memset(&ifr, 0, sizeof(ifr)); - estrlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (prog_ioctl(s, SIOCGIFFLAGS, &ifr) == -1) - return -1; - - *flagsp = (unsigned short)ifr.ifr_flags; - - prop_dictionary_set_uint64(oenv, "ifflags", - (unsigned short)ifr.ifr_flags); - - return 0; -} - -const char * -getifinfo(prop_dictionary_t env, prop_dictionary_t oenv, unsigned short *flagsp) -{ - if (getifflags(env, oenv, flagsp) == -1) - return NULL; - - return getifname(env); -} - -const char * -getifname(prop_dictionary_t env) -{ - const char *s; - - return prop_dictionary_get_cstring_nocopy(env, "if", &s) ? s : NULL; -} - -ssize_t -getargdata(prop_dictionary_t env, const char *key, uint8_t *buf, size_t buflen) -{ - prop_data_t data; - size_t datalen; - - data = (prop_data_t)prop_dictionary_get(env, key); - if (data == NULL) { - errno = ENOENT; - return -1; - } - datalen = prop_data_size(data); - if (datalen > buflen) { - errno = ENAMETOOLONG; - return -1; - } - memset(buf, 0, buflen); - memcpy(buf, prop_data_data_nocopy(data), datalen); - return datalen; -} - -ssize_t -getargstr(prop_dictionary_t env, const char *key, char *buf, size_t buflen) -{ - prop_data_t data; - size_t datalen; - - data = (prop_data_t)prop_dictionary_get(env, key); - if (data == NULL) { - errno = ENOENT; - return -1; - } - datalen = prop_data_size(data); - if (datalen >= buflen) { - errno = ENAMETOOLONG; - return -1; - } - memset(buf, 0, buflen); - memcpy(buf, prop_data_data_nocopy(data), datalen); - return datalen; -} - -int -getaf(prop_dictionary_t env) -{ - int64_t af; - - if (!prop_dictionary_get_int64(env, "af", &af)) { - errno = ENOENT; - return -1; - } - return (int)af; -} diff --git a/sbin/ifconfig/ether.c b/sbin/ifconfig/ether.c deleted file mode 100644 index 25d1f00bd..000000000 --- a/sbin/ifconfig/ether.c +++ /dev/null @@ -1,99 +0,0 @@ -/* $NetBSD: ether.c,v 1.2 2012/11/01 13:43:23 pgoyette Exp $ */ - -/* - * Copyright (c) 1983, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#ifndef lint -__RCSID("$NetBSD: ether.c,v 1.2 2012/11/01 13:43:23 pgoyette Exp $"); -#endif /* not lint */ - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "env.h" -#include "parse.h" -#include "extern.h" -#include "prog_ops.h" - -static void ether_status(prop_dictionary_t, prop_dictionary_t); -static void ether_constructor(void) __attribute__((constructor)); - -static status_func_t status; - -#define MAX_PRINT_LEN 55 - -void -ether_status(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct eccapreq eccr; - char fbuf[BUFSIZ]; - char *bp; - - memset(&eccr, 0, sizeof(eccr)); - - if (direct_ioctl(env, SIOCGETHERCAP, &eccr) == -1) - return; - - if (eccr.eccr_capabilities != 0) { - (void)snprintb_m(fbuf, sizeof(fbuf), ECCAPBITS, - eccr.eccr_capabilities, MAX_PRINT_LEN); - bp = fbuf; - while (*bp != '\0') { - printf("\tec_capabilities=%s\n", &bp[2]); - bp += strlen(bp) + 1; - } - (void)snprintb_m(fbuf, sizeof(fbuf), ECCAPBITS, - eccr.eccr_capenable, MAX_PRINT_LEN); - bp = fbuf; - while (*bp != '\0') { - printf("\tec_enabled=%s\n", &bp[2]); - bp += strlen(bp) + 1; - } - } -} - -static void -ether_constructor(void) -{ - - status_func_init(&status, ether_status); - register_status(&status); -} diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c deleted file mode 100644 index 1af088203..000000000 --- a/sbin/ifconfig/ifconfig.c +++ /dev/null @@ -1,1476 +0,0 @@ -/* $NetBSD: ifconfig.c,v 1.235 2015/07/29 07:42:27 ozaki-r Exp $ */ - -/*- - * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, - * NASA Ames Research Center. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Copyright (c) 1983, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1983, 1993\ - The Regents of the University of California. All rights reserved."); -__RCSID("$NetBSD: ifconfig.c,v 1.235 2015/07/29 07:42:27 ozaki-r Exp $"); -#endif /* not lint */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include /* XXX */ -#include /* XXX */ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "extern.h" - -#include "media.h" -#include "parse.h" -#include "env.h" -#include "prog_ops.h" - -#define WAIT_DAD 10000000 /* nanoseconds between each poll, 10ms */ - -static bool bflag, dflag, hflag, sflag, uflag, wflag; -bool lflag, Nflag, vflag, zflag; -static long wflag_secs; - -static char gflags[10 + 26 * 2 + 1] = "AabCdhlNsuvw:z"; -bool gflagset[10 + 26 * 2]; - -static int carrier(prop_dictionary_t); -static int clone_command(prop_dictionary_t, prop_dictionary_t); -static void do_setifpreference(prop_dictionary_t); -static int flag_index(int); -static void init_afs(void); -static int list_cloners(prop_dictionary_t, prop_dictionary_t); -static int media_status_exec(prop_dictionary_t, prop_dictionary_t); -static int wait_dad_exec(prop_dictionary_t, prop_dictionary_t); -static int no_cmds_exec(prop_dictionary_t, prop_dictionary_t); -static int notrailers(prop_dictionary_t, prop_dictionary_t); -static void printall(const char *, prop_dictionary_t); -static int setifaddr(prop_dictionary_t, prop_dictionary_t); -static int setifbroadaddr(prop_dictionary_t, prop_dictionary_t); -static int setifcaps(prop_dictionary_t, prop_dictionary_t); -static int setifdstormask(prop_dictionary_t, prop_dictionary_t); -static int setifflags(prop_dictionary_t, prop_dictionary_t); -static int setifmetric(prop_dictionary_t, prop_dictionary_t); -static int setifmtu(prop_dictionary_t, prop_dictionary_t); -static int setifnetmask(prop_dictionary_t, prop_dictionary_t); -static int setifprefixlen(prop_dictionary_t, prop_dictionary_t); -static int setlinkstr(prop_dictionary_t, prop_dictionary_t); -static int unsetlinkstr(prop_dictionary_t, prop_dictionary_t); -static void status(const struct sockaddr *, prop_dictionary_t, - prop_dictionary_t); -__dead static void usage(void); - -static const struct kwinst ifflagskw[] = { - IFKW("arp", -IFF_NOARP) - , IFKW("debug", IFF_DEBUG) - , IFKW("link0", IFF_LINK0) - , IFKW("link1", IFF_LINK1) - , IFKW("link2", IFF_LINK2) - , {.k_word = "down", .k_type = KW_T_INT, .k_int = -IFF_UP} - , {.k_word = "up", .k_type = KW_T_INT, .k_int = IFF_UP} -}; - -static const struct kwinst ifcapskw[] = { - IFKW("ip4csum-tx", IFCAP_CSUM_IPv4_Tx) - , IFKW("ip4csum-rx", IFCAP_CSUM_IPv4_Rx) - , IFKW("tcp4csum-tx", IFCAP_CSUM_TCPv4_Tx) - , IFKW("tcp4csum-rx", IFCAP_CSUM_TCPv4_Rx) - , IFKW("udp4csum-tx", IFCAP_CSUM_UDPv4_Tx) - , IFKW("udp4csum-rx", IFCAP_CSUM_UDPv4_Rx) - , IFKW("tcp6csum-tx", IFCAP_CSUM_TCPv6_Tx) - , IFKW("tcp6csum-rx", IFCAP_CSUM_TCPv6_Rx) - , IFKW("udp6csum-tx", IFCAP_CSUM_UDPv6_Tx) - , IFKW("udp6csum-rx", IFCAP_CSUM_UDPv6_Rx) - , IFKW("ip4csum", IFCAP_CSUM_IPv4_Tx|IFCAP_CSUM_IPv4_Rx) - , IFKW("tcp4csum", IFCAP_CSUM_TCPv4_Tx|IFCAP_CSUM_TCPv4_Rx) - , IFKW("udp4csum", IFCAP_CSUM_UDPv4_Tx|IFCAP_CSUM_UDPv4_Rx) - , IFKW("tcp6csum", IFCAP_CSUM_TCPv6_Tx|IFCAP_CSUM_TCPv6_Rx) - , IFKW("udp6csum", IFCAP_CSUM_UDPv6_Tx|IFCAP_CSUM_UDPv6_Rx) - , IFKW("tso4", IFCAP_TSOv4) - , IFKW("tso6", IFCAP_TSOv6) -}; - -extern struct pbranch command_root; -extern struct pbranch opt_command; -extern struct pbranch opt_family, opt_silent_family; -extern struct pkw cloning, silent_family, family, ifcaps, ifflags, misc; -extern struct pstr parse_linkstr; - -struct pinteger parse_metric = PINTEGER_INITIALIZER(&parse_metric, "metric", 10, - setifmetric, "metric", &command_root.pb_parser); - -struct pinteger parse_mtu = PINTEGER_INITIALIZER(&parse_mtu, "mtu", 10, - setifmtu, "mtu", &command_root.pb_parser); - -struct pinteger parse_prefixlen = PINTEGER_INITIALIZER(&parse_prefixlen, - "prefixlen", 10, setifprefixlen, "prefixlen", &command_root.pb_parser); - -struct pinteger parse_preference = PINTEGER_INITIALIZER1(&parse_preference, - "preference", INT16_MIN, INT16_MAX, 10, NULL, "preference", - &command_root.pb_parser); - -struct paddr parse_netmask = PADDR_INITIALIZER(&parse_netmask, "netmask", - setifnetmask, "dstormask", NULL, NULL, NULL, &command_root.pb_parser); - -struct paddr parse_broadcast = PADDR_INITIALIZER(&parse_broadcast, - "broadcast address", - setifbroadaddr, "broadcast", NULL, NULL, NULL, &command_root.pb_parser); - -static const struct kwinst misckw[] = { - {.k_word = "alias", .k_key = "alias", .k_deact = "alias", - .k_type = KW_T_BOOL, .k_neg = true, - .k_bool = true, .k_negbool = false, - .k_nextparser = &command_root.pb_parser} - , {.k_word = "broadcast", .k_nextparser = &parse_broadcast.pa_parser} - , {.k_word = "delete", .k_key = "alias", .k_deact = "alias", - .k_type = KW_T_BOOL, .k_bool = false, - .k_nextparser = &command_root.pb_parser} - , {.k_word = "metric", .k_nextparser = &parse_metric.pi_parser} - , {.k_word = "mtu", .k_nextparser = &parse_mtu.pi_parser} - , {.k_word = "netmask", .k_nextparser = &parse_netmask.pa_parser} - , {.k_word = "preference", .k_act = "address", - .k_nextparser = &parse_preference.pi_parser} - , {.k_word = "prefixlen", .k_nextparser = &parse_prefixlen.pi_parser} - , {.k_word = "trailers", .k_neg = true, - .k_exec = notrailers, .k_nextparser = &command_root.pb_parser} - , {.k_word = "linkstr", .k_nextparser = &parse_linkstr.ps_parser } - , {.k_word = "-linkstr", .k_exec = unsetlinkstr, - .k_nextparser = &command_root.pb_parser } -}; - -/* key: clonecmd */ -static const struct kwinst clonekw[] = { - {.k_word = "create", .k_type = KW_T_INT, .k_int = SIOCIFCREATE, - .k_nextparser = &opt_silent_family.pb_parser}, - {.k_word = "destroy", .k_type = KW_T_INT, .k_int = SIOCIFDESTROY} -}; - -static struct kwinst familykw[24]; - -struct pterm cloneterm = PTERM_INITIALIZER(&cloneterm, "list cloners", - list_cloners, "none"); - -struct pterm wait_dad = PTERM_INITIALIZER(&wait_dad, "wait DAD", wait_dad_exec, - "none"); - -struct pterm no_cmds = PTERM_INITIALIZER(&no_cmds, "no commands", no_cmds_exec, - "none"); - -struct pkw family_only = - PKW_INITIALIZER(&family_only, "family-only", NULL, "af", familykw, - __arraycount(familykw), &no_cmds.pt_parser); - -struct paddr address = PADDR_INITIALIZER(&address, - "local address (address 1)", - setifaddr, "address", "netmask", NULL, "address", &command_root.pb_parser); - -struct paddr dstormask = PADDR_INITIALIZER(&dstormask, - "destination/netmask (address 2)", - setifdstormask, "dstormask", NULL, "address", "dstormask", - &command_root.pb_parser); - -struct paddr broadcast = PADDR_INITIALIZER(&broadcast, - "broadcast address (address 3)", - setifbroadaddr, "broadcast", NULL, "dstormask", "broadcast", - &command_root.pb_parser); - -struct pstr parse_linkstr = PSTR_INITIALIZER(&parse_linkstr, "linkstr", - setlinkstr, "linkstr", &command_root.pb_parser); - -static SIMPLEQ_HEAD(, afswtch) aflist = SIMPLEQ_HEAD_INITIALIZER(aflist); - -static SIMPLEQ_HEAD(, usage_func) usage_funcs = - SIMPLEQ_HEAD_INITIALIZER(usage_funcs); -static SIMPLEQ_HEAD(, status_func) status_funcs = - SIMPLEQ_HEAD_INITIALIZER(status_funcs); -static SIMPLEQ_HEAD(, statistics_func) statistics_funcs = - SIMPLEQ_HEAD_INITIALIZER(statistics_funcs); -static SIMPLEQ_HEAD(, cmdloop_branch) cmdloop_branches = - SIMPLEQ_HEAD_INITIALIZER(cmdloop_branches); - -struct branch opt_clone_brs[] = { - {.b_nextparser = &cloning.pk_parser} - , {.b_nextparser = &opt_family.pb_parser} -}, opt_silent_family_brs[] = { - {.b_nextparser = &silent_family.pk_parser} - , {.b_nextparser = &command_root.pb_parser} -}, opt_family_brs[] = { - {.b_nextparser = &family.pk_parser} - , {.b_nextparser = &opt_command.pb_parser} -}, command_root_brs[] = { - {.b_nextparser = &ifflags.pk_parser} - , {.b_nextparser = &ifcaps.pk_parser} - , {.b_nextparser = &kwmedia.pk_parser} - , {.b_nextparser = &misc.pk_parser} - , {.b_nextparser = &address.pa_parser} - , {.b_nextparser = &dstormask.pa_parser} - , {.b_nextparser = &broadcast.pa_parser} - , {.b_nextparser = NULL} -}, opt_command_brs[] = { - {.b_nextparser = &no_cmds.pt_parser} - , {.b_nextparser = &command_root.pb_parser} -}; - -struct branch opt_family_only_brs[] = { - {.b_nextparser = &no_cmds.pt_parser} - , {.b_nextparser = &family_only.pk_parser} -}; -struct pbranch opt_family_only = PBRANCH_INITIALIZER(&opt_family_only, - "opt-family-only", opt_family_only_brs, - __arraycount(opt_family_only_brs), true); -struct pbranch opt_command = PBRANCH_INITIALIZER(&opt_command, - "optional command", - opt_command_brs, __arraycount(opt_command_brs), true); - -struct pbranch command_root = PBRANCH_INITIALIZER(&command_root, - "command-root", command_root_brs, __arraycount(command_root_brs), true); - -struct piface iface_opt_family_only = - PIFACE_INITIALIZER(&iface_opt_family_only, "iface-opt-family-only", - NULL, "if", &opt_family_only.pb_parser); - -struct pkw family = PKW_INITIALIZER(&family, "family", NULL, "af", - familykw, __arraycount(familykw), &opt_command.pb_parser); - -struct pkw silent_family = PKW_INITIALIZER(&silent_family, "silent family", - NULL, "af", familykw, __arraycount(familykw), &command_root.pb_parser); - -struct pkw *family_users[] = {&family_only, &family, &silent_family}; - -struct pkw ifcaps = PKW_INITIALIZER(&ifcaps, "ifcaps", setifcaps, - "ifcap", ifcapskw, __arraycount(ifcapskw), &command_root.pb_parser); - -struct pkw ifflags = PKW_INITIALIZER(&ifflags, "ifflags", setifflags, - "ifflag", ifflagskw, __arraycount(ifflagskw), &command_root.pb_parser); - -struct pkw cloning = PKW_INITIALIZER(&cloning, "cloning", clone_command, - "clonecmd", clonekw, __arraycount(clonekw), NULL); - -struct pkw misc = PKW_INITIALIZER(&misc, "misc", NULL, NULL, - misckw, __arraycount(misckw), NULL); - -struct pbranch opt_clone = PBRANCH_INITIALIZER(&opt_clone, - "opt-clone", opt_clone_brs, __arraycount(opt_clone_brs), true); - -struct pbranch opt_silent_family = PBRANCH_INITIALIZER(&opt_silent_family, - "optional silent family", opt_silent_family_brs, - __arraycount(opt_silent_family_brs), true); - -struct pbranch opt_family = PBRANCH_INITIALIZER(&opt_family, - "opt-family", opt_family_brs, __arraycount(opt_family_brs), true); - -struct piface iface_start = PIFACE_INITIALIZER(&iface_start, - "iface-opt-family", NULL, "if", &opt_clone.pb_parser); - -struct piface iface_only = PIFACE_INITIALIZER(&iface_only, "iface", - media_status_exec, "if", NULL); - -static bool -flag_is_registered(const char *flags, int flag) -{ - return flags != NULL && strchr(flags, flag) != NULL; -} - -static int -check_flag(const char *flags, int flag) -{ - if (flag_is_registered(flags, flag)) { - errno = EEXIST; - return -1; - } - - if (flag >= '0' && flag <= '9') - return 0; - if (flag >= 'a' && flag <= 'z') - return 0; - if (flag >= 'A' && flag <= 'Z') - return 0; - - errno = EINVAL; - return -1; -} - -void -cmdloop_branch_init(cmdloop_branch_t *b, struct parser *p) -{ - b->b_parser = p; -} - -void -statistics_func_init(statistics_func_t *f, statistics_cb_t func) -{ - f->f_func = func; -} - -void -status_func_init(status_func_t *f, status_cb_t func) -{ - f->f_func = func; -} - -void -usage_func_init(usage_func_t *f, usage_cb_t func) -{ - f->f_func = func; -} - -int -register_cmdloop_branch(cmdloop_branch_t *b) -{ - SIMPLEQ_INSERT_TAIL(&cmdloop_branches, b, b_next); - return 0; -} - -int -register_statistics(statistics_func_t *f) -{ - SIMPLEQ_INSERT_TAIL(&statistics_funcs, f, f_next); - return 0; -} - -int -register_status(status_func_t *f) -{ - SIMPLEQ_INSERT_TAIL(&status_funcs, f, f_next); - return 0; -} - -int -register_usage(usage_func_t *f) -{ - SIMPLEQ_INSERT_TAIL(&usage_funcs, f, f_next); - return 0; -} - -int -register_family(struct afswtch *af) -{ - SIMPLEQ_INSERT_TAIL(&aflist, af, af_next); - return 0; -} - -int -register_flag(int flag) -{ - if (check_flag(gflags, flag) == -1) - return -1; - - if (strlen(gflags) + 1 >= sizeof(gflags)) { - errno = ENOMEM; - return -1; - } - - gflags[strlen(gflags)] = flag; - - return 0; -} - -static int -flag_index(int flag) -{ - if (flag >= '0' && flag <= '9') - return flag - '0'; - if (flag >= 'a' && flag <= 'z') - return 10 + flag - 'a'; - if (flag >= 'A' && flag <= 'Z') - return 10 + 26 + flag - 'a'; - - errno = EINVAL; - return -1; -} - -static bool -set_flag(int flag) -{ - int idx; - - if ((idx = flag_index(flag)) == -1) - return false; - - return gflagset[idx] = true; -} - -bool -get_flag(int flag) -{ - int idx; - - if ((idx = flag_index(flag)) == -1) - return false; - - return gflagset[idx]; -} - -static struct parser * -init_parser(void) -{ - cmdloop_branch_t *b; - - if (parser_init(&iface_opt_family_only.pif_parser) == -1) - err(EXIT_FAILURE, "parser_init(iface_opt_family_only)"); - if (parser_init(&iface_only.pif_parser) == -1) - err(EXIT_FAILURE, "parser_init(iface_only)"); - if (parser_init(&iface_start.pif_parser) == -1) - err(EXIT_FAILURE, "parser_init(iface_start)"); - - SIMPLEQ_FOREACH(b, &cmdloop_branches, b_next) - pbranch_addbranch(&command_root, b->b_parser); - - return &iface_start.pif_parser; -} - -static int -no_cmds_exec(prop_dictionary_t env, prop_dictionary_t oenv) -{ - const char *ifname; - unsigned short ignore; - - /* ifname == NULL is ok. It indicates 'ifconfig -a'. */ - if ((ifname = getifname(env)) == NULL) - ; - else if (getifflags(env, oenv, &ignore) == -1) - err(EXIT_FAILURE, "SIOCGIFFLAGS %s", ifname); - - printall(ifname, env); - exit(EXIT_SUCCESS); -} - -static int -wait_dad_exec(prop_dictionary_t env, prop_dictionary_t oenv) -{ - bool waiting; - struct ifaddrs *ifaddrs, *ifa; - const struct timespec ts = { .tv_sec = 0, .tv_nsec = WAIT_DAD }; - const struct timespec add = { .tv_sec = wflag_secs, .tv_nsec = 0}; - struct timespec now, end = { .tv_sec = wflag_secs, .tv_nsec = 0}; - const struct afswtch *afp; - - if (wflag_secs) { - if (clock_gettime(CLOCK_MONOTONIC, &now) == -1) - err(EXIT_FAILURE, "clock_gettime"); - timespecadd(&now, &add, &end); - } - - if (getifaddrs(&ifaddrs) == -1) - err(EXIT_FAILURE, "getifaddrs"); - - for (;;) { - waiting = false; - for (ifa = ifaddrs; ifa; ifa = ifa->ifa_next) { - if (ifa->ifa_addr == NULL) - continue; - afp = lookup_af_bynum(ifa->ifa_addr->sa_family); - if (afp && afp->af_addr_tentative && - afp->af_addr_tentative(ifa)) - { - waiting = true; - break; - } - } - if (!waiting) - break; - nanosleep(&ts, NULL); - if (wflag_secs) { - if (clock_gettime(CLOCK_MONOTONIC, &now) == -1) - err(EXIT_FAILURE, "clock_gettime"); - if (timespeccmp(&now, &end, >)) - errx(EXIT_FAILURE, "timed out"); - } - } - - freeifaddrs(ifaddrs); - exit(EXIT_SUCCESS); -} - -static int -media_status_exec(prop_dictionary_t env, prop_dictionary_t oenv) -{ - const char *ifname; - unsigned short ignore; - - /* ifname == NULL is ok. It indicates 'ifconfig -a'. */ - if ((ifname = getifname(env)) == NULL) - ; - else if (getifflags(env, oenv, &ignore) == -1) - err(EXIT_FAILURE, "SIOCGIFFLAGS %s", ifname); - - exit(carrier(env)); -} - -static void -do_setifcaps(prop_dictionary_t env) -{ - struct ifcapreq ifcr; - prop_data_t d; - - d = (prop_data_t )prop_dictionary_get(env, "ifcaps"); - if (d == NULL) - return; - - assert(sizeof(ifcr) == prop_data_size(d)); - - memcpy(&ifcr, prop_data_data_nocopy(d), sizeof(ifcr)); - if (direct_ioctl(env, SIOCSIFCAP, &ifcr) == -1) - err(EXIT_FAILURE, "SIOCSIFCAP"); -} - -int -main(int argc, char **argv) -{ - const struct afswtch *afp; - int af, s; - bool aflag = false, Cflag = false; - struct match match[32]; - size_t nmatch; - struct parser *start; - int ch, narg = 0, rc; - prop_dictionary_t env, oenv; - const char *ifname; - char *end; - - memset(match, 0, sizeof(match)); - - init_afs(); - - start = init_parser(); - - /* Parse command-line options */ - Nflag = vflag = zflag = false; - aflag = argc == 1 ? true : false; - if (aflag) - start = &opt_family_only.pb_parser; - - while ((ch = getopt(argc, argv, gflags)) != -1) { - switch (ch) { - case 'A': - warnx("-A is deprecated"); - break; - - case 'a': - aflag = true; - break; - - case 'b': - bflag = true; - break; - - case 'C': - Cflag = true; - break; - - case 'd': - dflag = true; - break; - case 'h': - hflag = true; - break; - case 'l': - lflag = true; - break; - case 'N': - Nflag = true; - break; - - case 's': - sflag = true; - break; - - case 'u': - uflag = true; - break; - - case 'v': - vflag = true; - break; - - case 'w': - wflag = true; - wflag_secs = strtol(optarg, &end, 10); - if ((end != NULL && *end != '\0') || - wflag_secs < 0 || wflag_secs >= INT32_MAX) - errx(EXIT_FAILURE, "%s: not a number", optarg); - break; - - case 'z': - zflag = true; - break; - - default: - if (!set_flag(ch)) - usage(); - break; - } - switch (ch) { - case 'a': - start = &opt_family_only.pb_parser; - break; - - case 'L': - case 'm': - case 'z': - if (start != &opt_family_only.pb_parser) - start = &iface_opt_family_only.pif_parser; - break; - case 'C': - start = &cloneterm.pt_parser; - break; - case 'l': - start = &no_cmds.pt_parser; - break; - case 's': - if (start != &no_cmds.pt_parser && - start != &opt_family_only.pb_parser) - start = &iface_only.pif_parser; - break; - case 'w': - start = &wait_dad.pt_parser; - break; - default: - break; - } - } - argc -= optind; - argv += optind; - - /* - * -l means "list all interfaces", and is mutually exclusive with - * all other flags/commands. - * - * -C means "list all names of cloners", and it mutually exclusive - * with all other flags/commands. - * - * -a means "print status of all interfaces". - * - * -w means "spin until DAD completes for all addreseses", and is - * mutually exclusivewith all other flags/commands. - */ - if ((lflag || Cflag || wflag) && - (aflag || get_flag('m') || vflag || zflag)) - usage(); - if ((lflag || Cflag || wflag) && get_flag('L')) - usage(); - if ((lflag && Cflag) || (lflag & wflag) || (Cflag && wflag)) - usage(); - - nmatch = __arraycount(match); - - rc = parse(argc, argv, start, match, &nmatch, &narg); - if (rc != 0) - usage(); - - if (prog_init && prog_init() == -1) - err(1, "rump client init"); - - if ((oenv = prop_dictionary_create()) == NULL) - err(EXIT_FAILURE, "%s: prop_dictionary_create", __func__); - - if (matches_exec(match, oenv, nmatch) == -1) - err(EXIT_FAILURE, "exec_matches"); - - argc -= narg; - argv += narg; - - env = (nmatch > 0) ? match[(int)nmatch - 1].m_env : NULL; - if (env == NULL) - env = oenv; - else { - env = prop_dictionary_augment(env, oenv); - if (env == NULL) - err(EXIT_FAILURE, "%s: prop_dictionary_augment", - __func__); - } - - /* Process any media commands that may have been issued. */ - process_media_commands(env); - - if ((af = getaf(env)) == -1) - af = AF_INET; - - if ((s = getsock(af)) == -1) - err(EXIT_FAILURE, "%s: getsock", __func__); - - if ((ifname = getifname(env)) == NULL) - err(EXIT_FAILURE, "%s: getifname", __func__); - - if ((afp = lookup_af_bynum(af)) == NULL) - errx(EXIT_FAILURE, "%s: lookup_af_bynum", __func__); - - assert(afp->af_addr_commit != NULL); - (*afp->af_addr_commit)(env, oenv); - - do_setifpreference(env); - do_setifcaps(env); - - exit(EXIT_SUCCESS); -} - -static void -init_afs(void) -{ - size_t i; - const struct afswtch *afp; - struct kwinst kw = {.k_type = KW_T_INT}; - - SIMPLEQ_FOREACH(afp, &aflist, af_next) { - kw.k_word = afp->af_name; - kw.k_int = afp->af_af; - for (i = 0; i < __arraycount(familykw); i++) { - if (familykw[i].k_word == NULL) { - familykw[i] = kw; - break; - } - } - } -} - -const struct afswtch * -lookup_af_bynum(int afnum) -{ - const struct afswtch *afp; - - SIMPLEQ_FOREACH(afp, &aflist, af_next) { - if (afp->af_af == afnum) - break; - } - return afp; -} - -void -printall(const char *ifname, prop_dictionary_t env0) -{ - struct ifaddrs *ifap, *ifa; - struct ifreq ifr; - const struct sockaddr *sdl = NULL; - prop_dictionary_t env, oenv; - int idx; - char *p; - - if (env0 == NULL) - env = prop_dictionary_create(); - else - env = prop_dictionary_copy_mutable(env0); - - oenv = prop_dictionary_create(); - - if (env == NULL || oenv == NULL) - errx(EXIT_FAILURE, "%s: prop_dictionary_copy/create", __func__); - - if (getifaddrs(&ifap) != 0) - err(EXIT_FAILURE, "getifaddrs"); - p = NULL; - idx = 0; - for (ifa = ifap; ifa; ifa = ifa->ifa_next) { - memset(&ifr, 0, sizeof(ifr)); - estrlcpy(ifr.ifr_name, ifa->ifa_name, sizeof(ifr.ifr_name)); - if (sizeof(ifr.ifr_addr) >= ifa->ifa_addr->sa_len) { - memcpy(&ifr.ifr_addr, ifa->ifa_addr, - ifa->ifa_addr->sa_len); - } - - if (ifname != NULL && strcmp(ifname, ifa->ifa_name) != 0) - continue; - if (ifa->ifa_addr->sa_family == AF_LINK) - sdl = ifa->ifa_addr; - if (p && strcmp(p, ifa->ifa_name) == 0) - continue; - if (!prop_dictionary_set_cstring(env, "if", ifa->ifa_name)) - continue; - p = ifa->ifa_name; - - if (bflag && (ifa->ifa_flags & IFF_BROADCAST) == 0) - continue; - if (dflag && (ifa->ifa_flags & IFF_UP) != 0) - continue; - if (uflag && (ifa->ifa_flags & IFF_UP) == 0) - continue; - - if (sflag && carrier(env)) - continue; - idx++; - /* - * Are we just listing the interfaces? - */ - if (lflag) { - if (idx > 1) - printf(" "); - fputs(ifa->ifa_name, stdout); - continue; - } - - status(sdl, env, oenv); - sdl = NULL; - } - if (lflag) - printf("\n"); - prop_object_release((prop_object_t)env); - prop_object_release((prop_object_t)oenv); - freeifaddrs(ifap); -} - -static int -list_cloners(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct if_clonereq ifcr; - char *cp, *buf; - int idx, s; - - memset(&ifcr, 0, sizeof(ifcr)); - - s = getsock(AF_INET); - - if (prog_ioctl(s, SIOCIFGCLONERS, &ifcr) == -1) - err(EXIT_FAILURE, "SIOCIFGCLONERS for count"); - - buf = malloc(ifcr.ifcr_total * IFNAMSIZ); - if (buf == NULL) - err(EXIT_FAILURE, "unable to allocate cloner name buffer"); - - ifcr.ifcr_count = ifcr.ifcr_total; - ifcr.ifcr_buffer = buf; - - if (prog_ioctl(s, SIOCIFGCLONERS, &ifcr) == -1) - err(EXIT_FAILURE, "SIOCIFGCLONERS for names"); - - /* - * In case some disappeared in the mean time, clamp it down. - */ - if (ifcr.ifcr_count > ifcr.ifcr_total) - ifcr.ifcr_count = ifcr.ifcr_total; - - for (cp = buf, idx = 0; idx < ifcr.ifcr_count; idx++, cp += IFNAMSIZ) { - if (idx > 0) - printf(" "); - printf("%s", cp); - } - - printf("\n"); - free(buf); - exit(EXIT_SUCCESS); -} - -static int -clone_command(prop_dictionary_t env, prop_dictionary_t oenv) -{ - int64_t cmd; - - if (!prop_dictionary_get_int64(env, "clonecmd", &cmd)) { - errno = ENOENT; - return -1; - } - - if (indirect_ioctl(env, (unsigned long)cmd, NULL) == -1) { - warn("%s", __func__); - return -1; - } - return 0; -} - -/*ARGSUSED*/ -static int -setifaddr(prop_dictionary_t env, prop_dictionary_t oenv) -{ - const struct paddr_prefix *pfx0; - struct paddr_prefix *pfx; - prop_data_t d; - int af; - - if ((af = getaf(env)) == -1) - af = AF_INET; - - d = (prop_data_t)prop_dictionary_get(env, "address"); - assert(d != NULL); - pfx0 = prop_data_data_nocopy(d); - - if (pfx0->pfx_len >= 0) { - pfx = prefixlen_to_mask(af, pfx0->pfx_len); - if (pfx == NULL) - err(EXIT_FAILURE, "prefixlen_to_mask"); - free(pfx); - } - - return 0; -} - -static int -setifnetmask(prop_dictionary_t env, prop_dictionary_t oenv) -{ - prop_data_t d; - - d = (prop_data_t)prop_dictionary_get(env, "dstormask"); - assert(d != NULL); - - if (!prop_dictionary_set(oenv, "netmask", (prop_object_t)d)) - return -1; - - return 0; -} - -static int -setifbroadaddr(prop_dictionary_t env, prop_dictionary_t oenv) -{ - prop_data_t d; - unsigned short flags; - - if (getifflags(env, oenv, &flags) == -1) - err(EXIT_FAILURE, "%s: getifflags", __func__); - - if ((flags & IFF_BROADCAST) == 0) - errx(EXIT_FAILURE, "not a broadcast interface"); - - d = (prop_data_t)prop_dictionary_get(env, "broadcast"); - assert(d != NULL); - - if (!prop_dictionary_set(oenv, "broadcast", (prop_object_t)d)) - return -1; - - return 0; -} - -/*ARGSUSED*/ -static int -notrailers(prop_dictionary_t env, prop_dictionary_t oenv) -{ - puts("Note: trailers are no longer sent, but always received"); - return 0; -} - -/*ARGSUSED*/ -static int -setifdstormask(prop_dictionary_t env, prop_dictionary_t oenv) -{ - const char *key; - prop_data_t d; - unsigned short flags; - - if (getifflags(env, oenv, &flags) == -1) - err(EXIT_FAILURE, "%s: getifflags", __func__); - - d = (prop_data_t)prop_dictionary_get(env, "dstormask"); - assert(d != NULL); - - if ((flags & IFF_BROADCAST) == 0) { - key = "dst"; - } else { - key = "netmask"; - } - - if (!prop_dictionary_set(oenv, key, (prop_object_t)d)) - return -1; - - return 0; -} - -static int -setifflags(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct ifreq ifr; - int64_t ifflag; - bool rc; - - rc = prop_dictionary_get_int64(env, "ifflag", &ifflag); - assert(rc); - - if (direct_ioctl(env, SIOCGIFFLAGS, &ifr) == -1) - return -1; - - if (ifflag < 0) { - ifflag = -ifflag; - ifr.ifr_flags &= ~ifflag; - } else - ifr.ifr_flags |= ifflag; - - if (direct_ioctl(env, SIOCSIFFLAGS, &ifr) == -1) - return -1; - - return 0; -} - -static int -getifcaps(prop_dictionary_t env, prop_dictionary_t oenv, struct ifcapreq *oifcr) -{ - bool rc; - struct ifcapreq ifcr; - const struct ifcapreq *tmpifcr; - prop_data_t capdata; - - capdata = (prop_data_t)prop_dictionary_get(env, "ifcaps"); - - if (capdata != NULL) { - tmpifcr = prop_data_data_nocopy(capdata); - *oifcr = *tmpifcr; - return 0; - } - - (void)direct_ioctl(env, SIOCGIFCAP, &ifcr); - *oifcr = ifcr; - - capdata = prop_data_create_data(&ifcr, sizeof(ifcr)); - - rc = prop_dictionary_set(oenv, "ifcaps", capdata); - - prop_object_release((prop_object_t)capdata); - - return rc ? 0 : -1; -} - -static int -setifcaps(prop_dictionary_t env, prop_dictionary_t oenv) -{ - int64_t ifcap; - bool rc; - prop_data_t capdata; - struct ifcapreq ifcr; - - rc = prop_dictionary_get_int64(env, "ifcap", &ifcap); - assert(rc); - - if (getifcaps(env, oenv, &ifcr) == -1) - return -1; - - if (ifcap < 0) { - ifcap = -ifcap; - ifcr.ifcr_capenable &= ~ifcap; - } else - ifcr.ifcr_capenable |= ifcap; - - if ((capdata = prop_data_create_data(&ifcr, sizeof(ifcr))) == NULL) - return -1; - - rc = prop_dictionary_set(oenv, "ifcaps", capdata); - prop_object_release((prop_object_t)capdata); - - return rc ? 0 : -1; -} - -static int -setifmetric(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct ifreq ifr; - bool rc; - int64_t metric; - - rc = prop_dictionary_get_int64(env, "metric", &metric); - assert(rc); - - ifr.ifr_metric = metric; - if (direct_ioctl(env, SIOCSIFMETRIC, &ifr) == -1) - warn("SIOCSIFMETRIC"); - return 0; -} - -static void -do_setifpreference(prop_dictionary_t env) -{ - struct if_addrprefreq ifap; - prop_data_t d; - const struct paddr_prefix *pfx; - - memset(&ifap, 0, sizeof(ifap)); - - if (!prop_dictionary_get_int16(env, "preference", - &ifap.ifap_preference)) - return; - - d = (prop_data_t)prop_dictionary_get(env, "address"); - assert(d != NULL); - - pfx = prop_data_data_nocopy(d); - - memcpy(&ifap.ifap_addr, &pfx->pfx_addr, - MIN(sizeof(ifap.ifap_addr), pfx->pfx_addr.sa_len)); - if (direct_ioctl(env, SIOCSIFADDRPREF, &ifap) == -1) - warn("SIOCSIFADDRPREF"); -} - -static int -setifmtu(prop_dictionary_t env, prop_dictionary_t oenv) -{ - int64_t mtu; - bool rc; - struct ifreq ifr; - - rc = prop_dictionary_get_int64(env, "mtu", &mtu); - assert(rc); - - ifr.ifr_mtu = mtu; - if (direct_ioctl(env, SIOCSIFMTU, &ifr) == -1) - warn("SIOCSIFMTU"); - - return 0; -} - -static int -carrier(prop_dictionary_t env) -{ - struct ifmediareq ifmr; - - memset(&ifmr, 0, sizeof(ifmr)); - - if (direct_ioctl(env, SIOCGIFMEDIA, &ifmr) == -1) { - /* - * Interface doesn't support SIOC{G,S}IFMEDIA; - * assume ok. - */ - return EXIT_SUCCESS; - } - if ((ifmr.ifm_status & IFM_AVALID) == 0) { - /* - * Interface doesn't report media-valid status. - * assume ok. - */ - return EXIT_SUCCESS; - } - /* otherwise, return ok for active, not-ok if not active. */ - if (ifmr.ifm_status & IFM_ACTIVE) - return EXIT_SUCCESS; - else - return EXIT_FAILURE; -} - -static void -print_plural(const char *prefix, uint64_t n, const char *unit) -{ - printf("%s%" PRIu64 " %s%s", prefix, n, unit, (n == 1) ? "" : "s"); -} - -static void -print_human_bytes(bool humanize, uint64_t n) -{ - char buf[5]; - - if (humanize) { - (void)humanize_number(buf, sizeof(buf), - (int64_t)n, "", HN_AUTOSCALE, HN_NOSPACE | HN_DECIMAL); - printf(", %s byte%s", buf, (atof(buf) == 1.0) ? "" : "s"); - } else - print_plural(", ", n, "byte"); -} - -/* - * Print the status of the interface. If an address family was - * specified, show it and it only; otherwise, show them all. - */ - -#define MAX_PRINT_LEN 58 /* XXX need a better way to determine this! */ - -void -status(const struct sockaddr *sdl, prop_dictionary_t env, - prop_dictionary_t oenv) -{ - const struct if_data *ifi; - status_func_t *status_f; - statistics_func_t *statistics_f; - struct ifdatareq ifdr; - struct ifreq ifr; - struct ifdrv ifdrv; - char fbuf[BUFSIZ]; - char *bp; - int af, s; - const char *ifname; - struct ifcapreq ifcr; - unsigned short flags; - const struct afswtch *afp; - - if ((af = getaf(env)) == -1) { - afp = NULL; - af = AF_UNSPEC; - } else - afp = lookup_af_bynum(af); - - /* get out early if the family is unsupported by the kernel */ - if ((s = getsock(af)) == -1) - err(EXIT_FAILURE, "%s: getsock", __func__); - - if ((ifname = getifinfo(env, oenv, &flags)) == NULL) - err(EXIT_FAILURE, "%s: getifinfo", __func__); - - (void)snprintb(fbuf, sizeof(fbuf), IFFBITS, flags); - printf("%s: flags=%s", ifname, fbuf); - - estrlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (prog_ioctl(s, SIOCGIFMETRIC, &ifr) == -1) - warn("SIOCGIFMETRIC %s", ifr.ifr_name); - else if (ifr.ifr_metric != 0) - printf(" metric %d", ifr.ifr_metric); - - estrlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (prog_ioctl(s, SIOCGIFMTU, &ifr) != -1 && ifr.ifr_mtu != 0) - printf(" mtu %d", ifr.ifr_mtu); - printf("\n"); - - if (getifcaps(env, oenv, &ifcr) == -1) - err(EXIT_FAILURE, "%s: getifcaps", __func__); - - if (ifcr.ifcr_capabilities != 0) { - (void)snprintb_m(fbuf, sizeof(fbuf), IFCAPBITS, - ifcr.ifcr_capabilities, MAX_PRINT_LEN); - bp = fbuf; - while (*bp != '\0') { - printf("\tcapabilities=%s\n", &bp[2]); - bp += strlen(bp) + 1; - } - (void)snprintb_m(fbuf, sizeof(fbuf), IFCAPBITS, - ifcr.ifcr_capenable, MAX_PRINT_LEN); - bp = fbuf; - while (*bp != '\0') { - printf("\tenabled=%s\n", &bp[2]); - bp += strlen(bp) + 1; - } - } - - SIMPLEQ_FOREACH(status_f, &status_funcs, f_next) - (*status_f->f_func)(env, oenv); - - print_link_addresses(env, true); - - estrlcpy(ifdrv.ifd_name, ifname, sizeof(ifdrv.ifd_name)); - ifdrv.ifd_cmd = IFLINKSTR_QUERYLEN; - ifdrv.ifd_len = 0; - ifdrv.ifd_data = NULL; - /* interface supports linkstr? */ - if (prog_ioctl(s, SIOCGLINKSTR, &ifdrv) != -1) { - char *p; - - p = malloc(ifdrv.ifd_len); - if (p == NULL) - err(EXIT_FAILURE, "malloc linkstr buf failed"); - ifdrv.ifd_data = p; - ifdrv.ifd_cmd = 0; - if (prog_ioctl(s, SIOCGLINKSTR, &ifdrv) == -1) - err(EXIT_FAILURE, "failed to query linkstr"); - printf("\tlinkstr: %s\n", (char *)ifdrv.ifd_data); - free(p); - } - - media_status(env, oenv); - - if (!vflag && !zflag) - goto proto_status; - - estrlcpy(ifdr.ifdr_name, ifname, sizeof(ifdr.ifdr_name)); - - if (prog_ioctl(s, zflag ? SIOCZIFDATA : SIOCGIFDATA, &ifdr) == -1) - err(EXIT_FAILURE, zflag ? "SIOCZIFDATA" : "SIOCGIFDATA"); - - ifi = &ifdr.ifdr_data; - - print_plural("\tinput: ", ifi->ifi_ipackets, "packet"); - print_human_bytes(hflag, ifi->ifi_ibytes); - if (ifi->ifi_imcasts) - print_plural(", ", ifi->ifi_imcasts, "multicast"); - if (ifi->ifi_ierrors) - print_plural(", ", ifi->ifi_ierrors, "error"); - if (ifi->ifi_iqdrops) - print_plural(", ", ifi->ifi_iqdrops, "queue drop"); - if (ifi->ifi_noproto) - printf(", %" PRIu64 " unknown protocol", ifi->ifi_noproto); - print_plural("\n\toutput: ", ifi->ifi_opackets, "packet"); - print_human_bytes(hflag, ifi->ifi_obytes); - if (ifi->ifi_omcasts) - print_plural(", ", ifi->ifi_omcasts, "multicast"); - if (ifi->ifi_oerrors) - print_plural(", ", ifi->ifi_oerrors, "error"); - if (ifi->ifi_collisions) - print_plural(", ", ifi->ifi_collisions, "collision"); - printf("\n"); - - SIMPLEQ_FOREACH(statistics_f, &statistics_funcs, f_next) - (*statistics_f->f_func)(env); - - proto_status: - - if (afp != NULL) - (*afp->af_status)(env, oenv, true); - else SIMPLEQ_FOREACH(afp, &aflist, af_next) - (*afp->af_status)(env, oenv, false); -} - -static int -setifprefixlen(prop_dictionary_t env, prop_dictionary_t oenv) -{ - bool rc; - int64_t plen; - int af; - struct paddr_prefix *pfx; - prop_data_t d; - - if ((af = getaf(env)) == -1) - af = AF_INET; - - rc = prop_dictionary_get_int64(env, "prefixlen", &plen); - assert(rc); - - pfx = prefixlen_to_mask(af, plen); - if (pfx == NULL) - err(EXIT_FAILURE, "prefixlen_to_mask"); - - d = prop_data_create_data(pfx, paddr_prefix_size(pfx)); - if (d == NULL) - err(EXIT_FAILURE, "%s: prop_data_create_data", __func__); - - if (!prop_dictionary_set(oenv, "netmask", (prop_object_t)d)) - err(EXIT_FAILURE, "%s: prop_dictionary_set", __func__); - - free(pfx); - return 0; -} - -static int -setlinkstr(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct ifdrv ifdrv; - size_t linkstrlen; - prop_data_t data; - char *linkstr; - - data = (prop_data_t)prop_dictionary_get(env, "linkstr"); - if (data == NULL) { - errno = ENOENT; - return -1; - } - linkstrlen = prop_data_size(data)+1; - - linkstr = malloc(linkstrlen); - if (linkstr == NULL) - err(EXIT_FAILURE, "malloc linkstr space"); - if (getargstr(env, "linkstr", linkstr, linkstrlen) == -1) - errx(EXIT_FAILURE, "getargstr linkstr failed"); - - ifdrv.ifd_cmd = 0; - ifdrv.ifd_len = linkstrlen; - ifdrv.ifd_data = __UNCONST(linkstr); - - if (direct_ioctl(env, SIOCSLINKSTR, &ifdrv) == -1) - err(EXIT_FAILURE, "SIOCSLINKSTR"); - free(linkstr); - - return 0; -} - -static int -unsetlinkstr(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct ifdrv ifdrv; - - memset(&ifdrv, 0, sizeof(ifdrv)); - ifdrv.ifd_cmd = IFLINKSTR_UNSET; - - if (direct_ioctl(env, SIOCSLINKSTR, &ifdrv) == -1) - err(EXIT_FAILURE, "SIOCSLINKSTR"); - - return 0; -} - -static void -usage(void) -{ - const char *progname = getprogname(); - usage_func_t *usage_f; - prop_dictionary_t env; - - if ((env = prop_dictionary_create()) == NULL) - err(EXIT_FAILURE, "%s: prop_dictionary_create", __func__); - - fprintf(stderr, "usage: %s [-h] %s[-v] [-z] %sinterface\n" - "\t[ af [ address [ dest_addr ] ] [ netmask mask ] [ prefixlen n ]\n" - "\t\t[ alias | -alias ] ]\n" - "\t[ up ] [ down ] [ metric n ] [ mtu n ]\n", progname, - flag_is_registered(gflags, 'm') ? "[-m] " : "", - flag_is_registered(gflags, 'L') ? "[-L] " : ""); - - SIMPLEQ_FOREACH(usage_f, &usage_funcs, f_next) - (*usage_f->f_func)(env); - - fprintf(stderr, - "\t[ arp | -arp ]\n" - "\t[ preference n ]\n" - "\t[ link0 | -link0 ] [ link1 | -link1 ] [ link2 | -link2 ]\n" - " %s -a [-b] [-d] [-h] %s[-u] [-v] [-z] [ af ]\n" - " %s -l [-b] [-d] [-s] [-u]\n" - " %s -C\n" - " %s -w n\n" - " %s interface create\n" - " %s interface destroy\n", - progname, flag_is_registered(gflags, 'm') ? "[-m] " : "", - progname, progname, progname, progname, progname); - - prop_object_release((prop_object_t)env); - exit(EXIT_FAILURE); -} diff --git a/sbin/ifconfig/ifconfig_hostops.c b/sbin/ifconfig/ifconfig_hostops.c deleted file mode 100644 index 4a5d5d154..000000000 --- a/sbin/ifconfig/ifconfig_hostops.c +++ /dev/null @@ -1,47 +0,0 @@ -/* $NetBSD: ifconfig_hostops.c,v 1.1 2010/12/13 17:35:08 pooka Exp $ */ - -/* - * Copyright (c) 2010 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifndef lint -__RCSID("$NetBSD: ifconfig_hostops.c,v 1.1 2010/12/13 17:35:08 pooka Exp $"); -#endif /* !lint */ - -#include -#include -#include - -#include - -#include "prog_ops.h" - -const struct prog_ops prog_ops = { - .op_socket = socket, - .op_ioctl = ioctl, - .op_read = read, - .op_close = close, -}; diff --git a/sbin/ifconfig/ifconfig_rumpops.c b/sbin/ifconfig/ifconfig_rumpops.c deleted file mode 100644 index 68afe8ca5..000000000 --- a/sbin/ifconfig/ifconfig_rumpops.c +++ /dev/null @@ -1,52 +0,0 @@ -/* $NetBSD: ifconfig_rumpops.c,v 1.1 2010/12/13 17:35:08 pooka Exp $ */ - -/* - * Copyright (c) 2010 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifndef lint -__RCSID("$NetBSD: ifconfig_rumpops.c,v 1.1 2010/12/13 17:35:08 pooka Exp $"); -#endif /* !lint */ - -#include -#include - -#include - -#include -#include -#include - -#include "prog_ops.h" - -const struct prog_ops prog_ops = { - .op_init = rumpclient_init, - - .op_socket = rump_sys_socket, - .op_ioctl = rump_sys_ioctl, - .op_read = rump_sys_read, - .op_close = rump_sys_close, -}; diff --git a/sbin/ifconfig/media.h b/sbin/ifconfig/media.h deleted file mode 100644 index 85ce6a678..000000000 --- a/sbin/ifconfig/media.h +++ /dev/null @@ -1,16 +0,0 @@ -/* $NetBSD: media.h,v 1.1 2008/07/02 07:44:15 dyoung Exp $ */ - -#ifndef _IFCONFIG_MEDIA_H -#define _IFCONFIG_MEDIA_H - -#include - -#include "parse.h" - -extern struct pkw kwmedia; - -void print_media_word(int, const char *); -void process_media_commands(prop_dictionary_t); -void media_status(prop_dictionary_t, prop_dictionary_t); - -#endif /* _IFCONFIG_MEDIA_H */ diff --git a/sbin/ifconfig/parse.c b/sbin/ifconfig/parse.c deleted file mode 100644 index 112a5ecc0..000000000 --- a/sbin/ifconfig/parse.c +++ /dev/null @@ -1,995 +0,0 @@ -/* $NetBSD: parse.c,v 1.18 2013/07/17 15:42:03 christos Exp $ */ - -/*- - * Copyright (c) 2008 David Young. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#ifndef lint -__RCSID("$NetBSD: parse.c,v 1.18 2013/07/17 15:42:03 christos Exp $"); -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "env.h" -#include "parse.h" -#include "util.h" - -#ifdef DEBUG -#define dbg_warnx(__fmt, ...) warnx(__fmt, __VA_ARGS__) -#else -#define dbg_warnx(__fmt, ...) /* empty */ -#endif - -static int parser_default_init(struct parser *); -static int pbranch_init(struct parser *); -static int pkw_init(struct parser *); - -static int pterm_match(const struct parser *, const struct match *, - struct match *, int, const char *); - -static int paddr_match(const struct parser *, const struct match *, - struct match *, int, const char *); - -static int pbranch_match(const struct parser *, const struct match *, - struct match *, int, const char *); - -static int piface_match(const struct parser *, const struct match *, - struct match *, int, const char *); - -static int pstr_match(const struct parser *, const struct match *, - struct match *, int, const char *); - -static int pinteger_match(const struct parser *, const struct match *, - struct match *, int, const char *); - -static int pkw_match(const struct parser *, const struct match *, - struct match *, int, const char *); - -const struct parser_methods pterm_methods = { - .pm_match = pterm_match - , .pm_init = NULL -}; - -const struct parser_methods pstr_methods = { - .pm_match = pstr_match - , .pm_init = parser_default_init -}; - -const struct parser_methods pinteger_methods = { - .pm_match = pinteger_match - , .pm_init = parser_default_init -}; - -const struct parser_methods paddr_methods = { - .pm_match = paddr_match - , .pm_init = parser_default_init -}; - -const struct parser_methods piface_methods = { - .pm_match = piface_match - , .pm_init = parser_default_init -}; - -const struct parser_methods pbranch_methods = { - .pm_match = pbranch_match - , .pm_init = pbranch_init -}; - -const struct parser_methods pkw_methods = { - .pm_match = pkw_match - , .pm_init = pkw_init -}; - -static int -match_setenv(const struct match *im, struct match *om, const char *key, - prop_object_t o) -{ - if (im == NULL) - om->m_env = prop_dictionary_create(); - else - om->m_env = prop_dictionary_copy(im->m_env); - - if (om->m_env == NULL) - goto delobj; - - if (key != NULL && !prop_dictionary_set(om->m_env, key, o)) - goto deldict; - - if (o != NULL) - prop_object_release((prop_object_t)o); - - return 0; -deldict: - prop_object_release((prop_object_t)om->m_env); - om->m_env = NULL; -delobj: - prop_object_release((prop_object_t)o); - errno = ENOMEM; - return -1; -} - -int -pstr_match(const struct parser *p, const struct match *im, struct match *om, - int argidx, const char *arg) -{ - prop_object_t o; - const struct pstr *ps = (const struct pstr *)p; - uint8_t buf[128]; - int len; - - if (arg == NULL) { - errno = EINVAL; - return -1; - } - - len = (int)sizeof(buf); - if (get_string(arg, NULL, buf, &len, ps->ps_hexok) == NULL) { - errno = EINVAL; - return -1; - } - - o = (prop_object_t)prop_data_create_data(buf, len); - - if (o == NULL) { - errno = ENOMEM; - return -1; - } - - if (match_setenv(im, om, ps->ps_key, o) == -1) - return -1; - - om->m_argidx = argidx; - om->m_parser = p; - om->m_nextparser = p->p_nextparser; - - return 0; -} - -int -pinteger_match(const struct parser *p, const struct match *im, struct match *om, - int argidx, const char *arg) -{ - prop_object_t o; - const struct pinteger *pi = (const struct pinteger *)p; - char *end; - int64_t val; - - if (arg == NULL) { - errno = EINVAL; - return -1; - } - - val = strtoimax(arg, &end, pi->pi_base); - if ((val == INTMAX_MIN || val == INTMAX_MAX) && errno == ERANGE) - return -1; - - if (*end != '\0') { - errno = EINVAL; - return -1; - } - - if (val < pi->pi_min || val > pi->pi_max) { - errno = ERANGE; - return -1; - } - - o = (prop_object_t)prop_number_create_integer(val); - - if (o == NULL) { - errno = ENOMEM; - return -1; - } - - if (match_setenv(im, om, pi->pi_key, o) == -1) - return -1; - - om->m_argidx = argidx; - om->m_parser = p; - om->m_nextparser = p->p_nextparser; - - return 0; -} - -static int -parse_linkaddr(const char *addr, struct sockaddr_storage *ss) -{ - static const size_t maxlen = - sizeof(*ss) - offsetof(struct sockaddr_dl, sdl_data[0]); - enum { - LLADDR_S_INITIAL = 0, - LLADDR_S_ONE_OCTET = 1, - LLADDR_S_TWO_OCTETS = 2, - LLADDR_S_COLON = 3 - } state = LLADDR_S_INITIAL; - uint8_t octet = 0, val; - struct sockaddr_dl *sdl; - const char *p; - size_t i; - - memset(ss, 0, sizeof(*ss)); - ss->ss_family = AF_LINK; - sdl = (struct sockaddr_dl *)ss; - - for (i = 0, p = addr; i < maxlen; p++) { - dbg_warnx("%s.%d: *p == %c, state %d", __func__, __LINE__, *p, - state); - if (*p == '\0') { - dbg_warnx("%s.%d", __func__, __LINE__); - if (state != LLADDR_S_ONE_OCTET && - state != LLADDR_S_TWO_OCTETS) - return -1; - dbg_warnx("%s.%d", __func__, __LINE__); - sdl->sdl_data[i++] = octet; - sdl->sdl_len = offsetof(struct sockaddr_dl, sdl_data) - + i * sizeof(sdl->sdl_data[0]); - sdl->sdl_alen = i; - return 0; - } - if (*p == ':') { - dbg_warnx("%s.%d", __func__, __LINE__); - if (state != LLADDR_S_ONE_OCTET && - state != LLADDR_S_TWO_OCTETS) - return -1; - dbg_warnx("%s.%d", __func__, __LINE__); - sdl->sdl_data[i++] = octet; - state = LLADDR_S_COLON; - continue; - } - if ('a' <= *p && *p <= 'f') - val = 10 + *p - 'a'; - else if ('A' <= *p && *p <= 'F') - val = 10 + *p - 'A'; - else if ('0' <= *p && *p <= '9') - val = *p - '0'; - else - return -1; - - dbg_warnx("%s.%d", __func__, __LINE__); - if (state == LLADDR_S_ONE_OCTET) { - state = LLADDR_S_TWO_OCTETS; - octet <<= 4; - octet |= val; - } else if (state != LLADDR_S_INITIAL && state != LLADDR_S_COLON) - return -1; - else { - state = LLADDR_S_ONE_OCTET; - octet = val; - } - dbg_warnx("%s.%d", __func__, __LINE__); - } - return -1; -} - -static int -paddr_match(const struct parser *p, const struct match *im, struct match *om, - int argidx, const char *arg0) -{ - unsigned int net, node; - int nread; - union { - struct sockaddr sa; - struct sockaddr_at sat; - struct sockaddr_in sin; - struct sockaddr_storage ss; - } u; - const struct paddr *pa = (const struct paddr *)p; - prop_data_t d; - prop_object_t o; - int64_t af0; - int af, rc; - struct paddr_prefix *pfx, *mask; - const struct sockaddr *sa = NULL; - struct addrinfo hints, *result = NULL; - char *arg, *end, *plen = NULL, *servname0; - const char *servname; - long prefixlen = -1; - size_t len; - - if (arg0 == NULL) { - errno = EINVAL; - return -1; - } - - if (pa->pa_activator != NULL && - prop_dictionary_get(im->m_env, pa->pa_activator) == NULL) - return -1; - - if (pa->pa_deactivator != NULL && - prop_dictionary_get(im->m_env, pa->pa_deactivator) != NULL) - return -1; - - if (!prop_dictionary_get_int64(im->m_env, "af", &af0)) - af = AF_UNSPEC; - else - af = af0; - - memset(&u, 0, sizeof(u)); - - switch (af) { - case AF_UNSPEC: - case AF_INET: - case AF_INET6: - if ((arg = strdup(arg0)) == NULL) - return -1; - - servname0 = arg; - (void)strsep(&servname0, ","); - servname = (servname0 == NULL) ? "0" : servname0; - - if (pa->pa_maskkey == NULL) - ; - else if ((plen = strrchr(arg, '/')) != NULL) - *plen++ = '\0'; - - memset(&hints, 0, sizeof(hints)); - - hints.ai_flags = AI_NUMERICHOST | AI_PASSIVE; - hints.ai_family = af; - hints.ai_socktype = SOCK_DGRAM; - - for (;;) { - rc = getaddrinfo(arg, servname, &hints, &result); - if (rc == 0) { - if (result->ai_next == NULL) - sa = result->ai_addr; - else - errno = EMLINK; - break; - } else if ((hints.ai_flags & AI_NUMERICHOST) != 0 && - (af == AF_INET || af == AF_UNSPEC) && - inet_aton(arg, &u.sin.sin_addr) == 1) { - u.sin.sin_family = AF_INET; - u.sin.sin_len = sizeof(u.sin); - sa = &u.sa; - break; - } else if ((hints.ai_flags & AI_NUMERICHOST) == 0 || - rc != EAI_NONAME) { - errno = ENOENT; - break; - } - hints.ai_flags &= ~AI_NUMERICHOST; - } - - - if (plen == NULL) - prefixlen = -1; - else { - prefixlen = strtol(plen, &end, 10); - if (end != NULL && *end != '\0') - sa = NULL; - if (prefixlen < 0 || prefixlen >= UINT8_MAX) { - errno = ERANGE; - sa = NULL; - } - } - - free(arg); - if (sa != NULL || af != AF_UNSPEC) - break; - /*FALLTHROUGH*/ - case AF_APPLETALK: - if (sscanf(arg0, "%u.%u%n", &net, &node, &nread) == 2 && - net != 0 && net <= 0xffff && node != 0 && node <= 0xfe && - arg0[nread] == '\0') { - u.sat.sat_family = AF_APPLETALK; - u.sat.sat_len = sizeof(u.sat); - u.sat.sat_addr.s_net = htons(net); - u.sat.sat_addr.s_node = node; - sa = &u.sa; - } - break; - case AF_LINK: - if (parse_linkaddr(arg0, &u.ss) == -1) - sa = NULL; - else - sa = &u.sa; - break; - } - - if (sa == NULL) - return -1; - - len = offsetof(struct paddr_prefix, pfx_addr) + sa->sa_len; - - if ((pfx = malloc(len)) == NULL) - return -1; - -#if 0 - { - int i; - - for (i = 0; i < sa->sa_len; i++) - printf(" %02x", ((const uint8_t *)sa)[i]); - printf("\n"); - } -#endif - - pfx->pfx_len = (int16_t)prefixlen; - memcpy(&pfx->pfx_addr, sa, sa->sa_len); - af = sa->sa_family; - - if (result != NULL) - freeaddrinfo(result); - - o = (prop_object_t)prop_data_create_data(pfx, len); - - free(pfx); - - if (o == NULL) - return -1; - - if (match_setenv(im, om, pa->pa_addrkey, o) == -1) - return -1; - - if (pa->pa_maskkey != NULL && plen != NULL) { - size_t masklen; - - if ((mask = prefixlen_to_mask(af, prefixlen)) == NULL) { - err(EXIT_FAILURE, "%s: prefixlen_to_mask(%d, %ld)", - __func__, af, prefixlen); - return -1; - } - - masklen = paddr_prefix_size(mask); - - d = prop_data_create_data(mask, masklen); - free(mask); - - if (d == NULL) { - err(EXIT_FAILURE, "%s: prop_data_create_data", - __func__); - return -1; - } - - rc = prop_dictionary_set(om->m_env, pa->pa_maskkey, - (prop_object_t)d) ? 0 : -1; - - prop_object_release((prop_object_t)d); - - if (rc != 0) { - err(EXIT_FAILURE, "%s: prop_dictionary_set", __func__); - return rc; - } - } - - om->m_argidx = argidx; - om->m_parser = p; - om->m_nextparser = p->p_nextparser; - return 0; -} - -static int -pterm_match(const struct parser *p, const struct match *im, - struct match *om, int argidx, const char *arg) -{ - const struct pterm *pt = (const struct pterm *)p; - prop_bool_t b; - - if (arg != NULL) { - errno = EINVAL; - return -1; - } - b = prop_bool_create(true); - - if (match_setenv(im, om, pt->pt_key, (prop_object_t)b) == -1) - return -1; - - om->m_argidx = argidx; - om->m_parser = p; - om->m_nextparser = NULL; - return 0; -} - -static int -piface_match(const struct parser *p, const struct match *im, - struct match *om, int argidx, const char *arg) -{ - const struct piface *pif = (const struct piface *)p; - prop_object_t o; - - if (arg == NULL || strlen(arg) > IFNAMSIZ) { - errno = EINVAL; - return -1; - } - - if ((o = (prop_object_t)prop_string_create_cstring(arg)) == NULL) { - errno = ENOMEM; - return -1; - } - - if (match_setenv(im, om, pif->pif_key, o) == -1) - return -1; - - om->m_argidx = argidx; - om->m_parser = p; - om->m_nextparser = p->p_nextparser; - return 0; -} - -static void -match_cleanup(struct match *dst) -{ - if (dst->m_env != NULL) - prop_object_release((prop_object_t)dst->m_env); - memset(dst, 0, sizeof(*dst)); -} - -static void -match_copy(struct match *dst, const struct match *src) -{ - match_cleanup(dst); - - prop_object_retain((prop_object_t)src->m_env); - *dst = *src; -} - -static int -pbranch_match(const struct parser *p, const struct match *im, - struct match *om, int argidx, const char *arg) -{ - const struct parser *nextp; - struct branch *b; - const struct pbranch *pb = (const struct pbranch *)p; - struct match tmpm; - int nforbid = 0, nmatch = 0, rc; - parser_match_t matchfunc; - - memset(&tmpm, 0, sizeof(tmpm)); - - SIMPLEQ_FOREACH(b, &pb->pb_branches, b_next) { - nextp = b->b_nextparser; - dbg_warnx("%s: b->b_nextparser %p [%s]", __func__, - nextp, nextp ? nextp->p_name : "(null)"); - if (nextp == NULL) { - if (arg == NULL) { - nmatch++; - match_setenv(im, om, NULL, NULL); - om->m_nextparser = NULL; - om->m_parser = p; - om->m_argidx = argidx; - } - continue; - } - matchfunc = nextp->p_methods->pm_match; - rc = (*matchfunc)(nextp, im, &tmpm, argidx, arg); - if (rc == 0) { - match_copy(om, &tmpm); - match_cleanup(&tmpm); - nmatch++; - dbg_warnx("%s: branch %s ok", __func__, nextp->p_name); - if (pb->pb_match_first) - break; - } else if (rc == 1) { - nforbid++; - if (pb->pb_match_first) - break; - } else { - dbg_warnx("%s: fail branch %s", __func__, - nextp->p_name); - } - } - switch (nmatch) { - case 0: - errno = ENOENT; - return (nforbid == 0) ? -1 : 1; - case 1: - dbg_warnx("%s: branch ok", __func__); - return 0; - default: - match_cleanup(om); - errno = EMLINK; - return -1; - } -} - -static int -pkw_match(const struct parser *p, const struct match *im, - struct match *om, int argidx, const char *arg) -{ - prop_object_t o = NULL; - struct kwinst *k; - union kwval *u = NULL; - const struct pkw *pk = (const struct pkw *)p; - - if (arg == NULL) { - errno = EINVAL; - return -1; - } - - SIMPLEQ_FOREACH(k, &pk->pk_keywords, k_next) { - if (k->k_act != NULL && - prop_dictionary_get(im->m_env, k->k_act) == NULL) - continue; - - if (k->k_neg && arg[0] == '-' && - strcmp(k->k_word, arg + 1) == 0) - u = &k->k_negu; - else if (strcmp(k->k_word, arg) == 0) - u = &k->k_u; - else - continue; - - if (k->k_altdeact != NULL && - prop_dictionary_get(im->m_env, k->k_altdeact) != NULL) - return 1; - - if (k->k_deact != NULL && - prop_dictionary_get(im->m_env, k->k_deact) != NULL) - return 1; - break; - } - if (k == NULL) { - errno = ENOENT; - return -1; - } - switch (k->k_type) { - case KW_T_NONE: - break; - case KW_T_BOOL: - o = (prop_object_t)prop_bool_create(u->u_bool); - if (o == NULL) - goto err; - break; - case KW_T_INT: - o = (prop_object_t)prop_number_create_integer(u->u_sint); - if (o == NULL) - goto err; - break; - case KW_T_UINT: - o = (prop_object_t)prop_number_create_unsigned_integer( - u->u_uint); - if (o == NULL) - goto err; - break; - case KW_T_OBJ: - o = u->u_obj; - break; - case KW_T_STR: - o = (prop_object_t)prop_string_create_cstring_nocopy(u->u_str); - if (o == NULL) - goto err; - break; - default: - errx(EXIT_FAILURE, "unknown keyword type %d", k->k_type); - } - - if (match_setenv(im, om, (o == NULL) ? NULL : k->k_key, o) == -1) - return -1; - - om->m_argidx = argidx; - om->m_parser = p; - om->m_nextparser = k->k_nextparser; - om->m_exec = k->k_exec; - return 0; -err: - errno = ENOMEM; - return -1; -} - -struct paddr * -paddr_create(const char *name, parser_exec_t pexec, const char *addrkey, - const char *maskkey, struct parser *next) -{ - struct paddr *pa; - - if ((pa = calloc(sizeof(*pa), 1)) == NULL) - return NULL; - - pa->pa_parser.p_methods = &paddr_methods; - pa->pa_parser.p_exec = pexec; - pa->pa_parser.p_name = name; - pa->pa_parser.p_nextparser = next; - - pa->pa_addrkey = addrkey; - pa->pa_maskkey = maskkey; - - return pa; -} - -struct piface * -piface_create(const char *name, parser_exec_t pexec, const char *defkey, - struct parser *defnext) -{ - struct piface *pif; - - if ((pif = calloc(sizeof(*pif), 1)) == NULL) - return NULL; - - pif->pif_parser.p_methods = &piface_methods; - pif->pif_parser.p_exec = pexec; - pif->pif_parser.p_name = name; - pif->pif_parser.p_nextparser = defnext; - - pif->pif_key = defkey; - - return pif; -} - -int -pbranch_addbranch(struct pbranch *pb, struct parser *p) -{ - struct branch *b; - - if ((b = malloc(sizeof(*b))) == NULL) - return -1; - b->b_nextparser = p; - SIMPLEQ_INSERT_HEAD(&pb->pb_branches, b, b_next); - pb->pb_parser.p_initialized = false; - return parser_init(&pb->pb_parser); -} - -int -pbranch_setbranches(struct pbranch *pb, const struct branch *brs, size_t nbr) -{ - struct branch *b; - size_t i; - - dbg_warnx("%s: nbr %zu", __func__, nbr); - - while ((b = SIMPLEQ_FIRST(&pb->pb_branches)) != NULL) { - SIMPLEQ_REMOVE_HEAD(&pb->pb_branches, b_next); - free(b); - } - - for (i = 0; i < nbr; i++) { - if ((b = malloc(sizeof(*b))) == NULL) - goto err; - *b = brs[i]; - dbg_warnx("%s: b->b_nextparser %p [%s]", __func__, - b->b_nextparser, b->b_nextparser ? b->b_nextparser->p_name - : "(null)"); - SIMPLEQ_INSERT_TAIL(&pb->pb_branches, b, b_next); - } - - return 0; -err: - while ((b = SIMPLEQ_FIRST(&pb->pb_branches)) != NULL) { - SIMPLEQ_REMOVE_HEAD(&pb->pb_branches, b_next); - free(b); - } - return -1; -} - -static int -pbranch_init(struct parser *p) -{ - struct branch *b; - struct pbranch *pb = (struct pbranch *)p; - struct parser *np; - - if (pb->pb_nbrinit == 0) - ; - else if (pbranch_setbranches(pb, pb->pb_brinit, pb->pb_nbrinit) == -1) - return -1; - - pb->pb_nbrinit = 0; - - SIMPLEQ_FOREACH(b, &pb->pb_branches, b_next) { - np = b->b_nextparser; - if (np != NULL && parser_init(np) == -1) - return -1; - } - return 0; -} - -struct pbranch * -pbranch_create(const char *name, const struct branch *brs, size_t nbr, - bool match_first) -{ - struct pbranch *pb; - - dbg_warnx("%s: nbr %zu", __func__, nbr); - - if ((pb = calloc(1, sizeof(*pb))) == NULL) - return NULL; - - pb->pb_parser.p_methods = &pbranch_methods; - pb->pb_parser.p_name = name; - - SIMPLEQ_INIT(&pb->pb_branches); - - if (pbranch_setbranches(pb, brs, nbr) == -1) - goto post_pb_err; - - pb->pb_match_first = match_first; - return pb; -post_pb_err: - free(pb); - return NULL; -} - -static int -parser_default_init(struct parser *p) -{ - struct parser *np; - - np = p->p_nextparser; - if (np != NULL && parser_init(np) == -1) - return -1; - - return 0; -} - -static int -pkw_setwords(struct pkw *pk, parser_exec_t defexec, const char *defkey, - const struct kwinst *kws, size_t nkw, struct parser *defnext) -{ - struct kwinst *k; - size_t i; - - for (i = 0; i < nkw; i++) { - if (kws[i].k_word == NULL) - continue; - if ((k = malloc(sizeof(*k))) == NULL) - goto post_pk_err; - *k = kws[i]; - if (k->k_nextparser == NULL) - k->k_nextparser = defnext; - if (k->k_key == NULL) - k->k_key = defkey; - if (k->k_exec == NULL) - k->k_exec = defexec; - SIMPLEQ_INSERT_TAIL(&pk->pk_keywords, k, k_next); - } - return 0; - -post_pk_err: - while ((k = SIMPLEQ_FIRST(&pk->pk_keywords)) != NULL) { - SIMPLEQ_REMOVE_HEAD(&pk->pk_keywords, k_next); - free(k); - } - return -1; -} - -static int -pkw_init(struct parser *p) -{ - struct kwinst *k; - struct pkw *pk = (struct pkw *)p; - struct parser *np; - - if (pk->pk_nkwinit == 0) - ; - else if (pkw_setwords(pk, pk->pk_execinit, pk->pk_keyinit, - pk->pk_kwinit, pk->pk_nkwinit, pk->pk_nextinit) == -1) - return -1; - - pk->pk_nkwinit = 0; - - SIMPLEQ_FOREACH(k, &pk->pk_keywords, k_next) { - np = k->k_nextparser; - if (np != NULL && parser_init(np) == -1) - return -1; - } - return 0; -} - -struct pkw * -pkw_create(const char *name, parser_exec_t defexec, const char *defkey, - const struct kwinst *kws, size_t nkw, struct parser *defnext) -{ - struct pkw *pk; - - if ((pk = calloc(1, sizeof(*pk))) == NULL) - return NULL; - - pk->pk_parser.p_methods = &pkw_methods; - pk->pk_parser.p_exec = defexec; - pk->pk_parser.p_name = name; - - SIMPLEQ_INIT(&pk->pk_keywords); - - if (pkw_setwords(pk, defexec, defkey, kws, nkw, defnext) == -1) - goto err; - - return pk; -err: - free(pk); - return NULL; -} - -int -parse(int argc, char **argv, const struct parser *p0, struct match *matches, - size_t *nmatch, int *narg) -{ - int i, rc = 0; - struct match *lastm = NULL, *m = matches; - const struct parser *p = p0; - - for (i = 0; i < argc && p != NULL; i++) { - if ((size_t)(m - matches) >= *nmatch) { - errno = EFBIG; - rc = -1; - break; - } - rc = (*p->p_methods->pm_match)(p, lastm, m, i, argv[i]); - if (rc != 0) - goto out; - p = m->m_nextparser; - lastm = m++; - } - for (; (size_t)(m - matches) < *nmatch && p != NULL; ) { - rc = (*p->p_methods->pm_match)(p, lastm, m, i, NULL); - if (rc != 0) - break; - p = m->m_nextparser; - lastm = m++; - } -out: - *nmatch = m - matches; - *narg = i; - return rc; -} - -int -matches_exec(const struct match *matches, prop_dictionary_t oenv, size_t nmatch) -{ - size_t i; - int rc = 0; - const struct match *m; - parser_exec_t pexec; - prop_dictionary_t d; - - for (i = 0; i < nmatch; i++) { - m = &matches[i]; - dbg_warnx("%s.%d: i %zu", __func__, __LINE__, i); - pexec = (m->m_parser->p_exec != NULL) - ? m->m_parser->p_exec : m->m_exec; - if (pexec == NULL) - continue; - dbg_warnx("%s.%d: m->m_parser->p_name %s", __func__, __LINE__, - m->m_parser->p_name); - d = prop_dictionary_augment(m->m_env, oenv); - rc = (*pexec)(d, oenv); - prop_object_release((prop_object_t)d); - if (rc == -1) - break; - } - return rc; -} - -int -parser_init(struct parser *p) -{ - if (p->p_initialized) - return 0; - p->p_initialized = true; - if (p->p_methods->pm_init == NULL) - return 0; - return (*p->p_methods->pm_init)(p); -} diff --git a/sbin/ifconfig/pfsync.c b/sbin/ifconfig/pfsync.c deleted file mode 100644 index c44f65621..000000000 --- a/sbin/ifconfig/pfsync.c +++ /dev/null @@ -1,229 +0,0 @@ -/* $NetBSD: pfsync.c,v 1.1 2009/09/14 10:36:49 degroote Exp $ */ -/*- - * Copyright (c) 2009 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifndef lint -__RCSID("$NetBSD: pfsync.c,v 1.1 2009/09/14 10:36:49 degroote Exp $"); -#endif /* not lint */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "env.h" -#include "parse.h" -#include "extern.h" - -static status_func_t status; -static usage_func_t usage; -static cmdloop_branch_t branch; - -static void pfsync_constructor(void) __attribute__((constructor)); -static void pfsync_status(prop_dictionary_t, prop_dictionary_t); -static int setpfsync_maxupd(prop_dictionary_t, prop_dictionary_t); -static int setpfsync_peer(prop_dictionary_t, prop_dictionary_t); -static int setpfsyncdev(prop_dictionary_t, prop_dictionary_t); - -struct pinteger parse_maxupd = PINTEGER_INITIALIZER1(&parse_maxupd, "maxupd", - 0, 255, 10, setpfsync_maxupd, "maxupd", &command_root.pb_parser); - -struct piface pfsyncdev = PIFACE_INITIALIZER(&pfsyncdev, "syncdev", setpfsyncdev, - "syncdev", &command_root.pb_parser); - -struct paddr parse_sync_peer = PADDR_INITIALIZER(&parse_sync_peer, "syncpeer", - setpfsync_peer, "syncpeer", NULL, NULL, NULL, &command_root.pb_parser); - -static const struct kwinst pfsynckw[] = { - {.k_word = "maxupd", .k_nextparser = &parse_maxupd.pi_parser}, - {.k_word = "syncdev", .k_nextparser = &pfsyncdev.pif_parser}, - {.k_word = "-syncdev", .k_key = "syncdev", .k_type = KW_T_STR, - .k_str = "", .k_exec = setpfsyncdev, - .k_nextparser = &command_root.pb_parser}, - {.k_word = "syncpeer", .k_nextparser = &parse_sync_peer.pa_parser}, - {.k_word = "-syncpeer", .k_key = "syncpeer", .k_type = KW_T_STR, - .k_str = "", .k_exec = setpfsync_peer, - .k_nextparser = &command_root.pb_parser} -}; - -struct pkw pfsync = PKW_INITIALIZER(&pfsync, "pfsync", NULL, NULL, - pfsynckw, __arraycount(pfsynckw), NULL); - -static void -pfsync_set(prop_dictionary_t env, struct pfsyncreq *pfsyncr) -{ - if (indirect_ioctl(env, SIOCSETPFSYNC, pfsyncr) == -1) - err(EXIT_FAILURE, "SIOCSETPFSYNC"); -} - -static int -pfsync_get1(prop_dictionary_t env, struct pfsyncreq *pfsyncr) -{ - memset(pfsyncr, 0, sizeof(*pfsyncr)); - - return indirect_ioctl(env, SIOCGETPFSYNC, pfsyncr); -} - -static void -pfsync_get(prop_dictionary_t env, struct pfsyncreq *pfsyncr) -{ - if (pfsync_get1(env, pfsyncr) == -1) - err(EXIT_FAILURE, "SIOCGETPFSYNC"); -} - -static void -pfsync_status(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct pfsyncreq pfsyncr; - - if (pfsync_get1(env, &pfsyncr) == -1) - return; - - if (pfsyncr.pfsyncr_syncdev[0] != '\0') { - printf("\tpfsync: syncdev: %s ", pfsyncr.pfsyncr_syncdev); - if (pfsyncr.pfsyncr_syncpeer.s_addr != INADDR_PFSYNC_GROUP) - printf("syncpeer: %s ", - inet_ntoa(pfsyncr.pfsyncr_syncpeer)); - printf("maxupd: %d\n", pfsyncr.pfsyncr_maxupdates); - } -} - -/* ARGSUSED */ -int -setpfsync_maxupd(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct pfsyncreq pfsyncr; - uint8_t maxupd; - - if (!prop_dictionary_get_uint8(env, "maxupd", &maxupd)) { - errno = ENOENT; - return -1; - } - - pfsync_get(env, &pfsyncr); - - pfsyncr.pfsyncr_maxupdates = maxupd; - - pfsync_set(env, &pfsyncr); - return 0; -} - - -/* ARGSUSED */ -int -setpfsyncdev(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct pfsyncreq pfsyncr; - const char *dev; - - if (!prop_dictionary_get_cstring_nocopy(env, "syncdev", &dev)) { - errno = ENOENT; - return -1; - } - - pfsync_get(env, &pfsyncr); - - strlcpy(pfsyncr.pfsyncr_syncdev, dev, sizeof(pfsyncr.pfsyncr_syncdev)); - - pfsync_set(env, &pfsyncr); - return 0; -} - -/* ARGSUSED */ -int -setpfsync_peer(prop_dictionary_t env, prop_dictionary_t oenv) -{ - struct pfsyncreq pfsyncr; - prop_data_t data; - const struct paddr_prefix *peerpfx; - const struct sockaddr_in *s; - - data = (prop_data_t)prop_dictionary_get(env, "syncpeer"); - if (data == NULL) { - errno = ENOENT; - return -1; - } - - pfsync_get(env, &pfsyncr); - - peerpfx = prop_data_data_nocopy(data); - - if (peerpfx != NULL) { - // Only AF_INET is supported for now - if (peerpfx->pfx_addr.sa_family != AF_INET) { - errno = ENOENT; - return -1; - } - - - s = (const struct sockaddr_in*)&peerpfx->pfx_addr; - - memcpy(&pfsyncr.pfsyncr_syncpeer.s_addr, &s->sin_addr, - MIN(sizeof(pfsyncr.pfsyncr_syncpeer.s_addr), - peerpfx->pfx_addr.sa_len)); - } else { - memset(&pfsyncr.pfsyncr_syncpeer.s_addr, 0, - sizeof(pfsyncr.pfsyncr_syncpeer.s_addr)); - } - - pfsync_set(env, &pfsyncr); - - return 0; -} - -static void -pfsync_usage(prop_dictionary_t env) -{ - fprintf(stderr, - "\t[ maxupd n ] [ syncdev iface ] [syncpeer peer_addr]\n"); -} - -static void -pfsync_constructor(void) -{ - cmdloop_branch_init(&branch, &pfsync.pk_parser); - register_cmdloop_branch(&branch); - status_func_init(&status, pfsync_status); - usage_func_init(&usage, pfsync_usage); - register_status(&status); - register_usage(&usage); -} diff --git a/sbin/ifconfig/tunnel.c b/sbin/ifconfig/tunnel.c deleted file mode 100644 index 6d808fc40..000000000 --- a/sbin/ifconfig/tunnel.c +++ /dev/null @@ -1,204 +0,0 @@ -/* $NetBSD: tunnel.c,v 1.20 2013/10/19 15:59:15 christos Exp $ */ - -/* - * Copyright (c) 1983, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#ifndef lint -__RCSID("$NetBSD: tunnel.c,v 1.20 2013/10/19 15:59:15 christos Exp $"); -#endif /* not lint */ - -#include -#include -#include - -#include - -#ifdef INET6 -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "env.h" -#include "extern.h" -#include "parse.h" -#include "util.h" - -static status_func_t status; -static usage_func_t usage; -static cmdloop_branch_t branch; - -static void tunnel_constructor(void) __attribute__((constructor)); -static int settunnel(prop_dictionary_t, prop_dictionary_t); -static int deletetunnel(prop_dictionary_t, prop_dictionary_t); -static void tunnel_status(prop_dictionary_t, prop_dictionary_t); - -struct paddr tundst = PADDR_INITIALIZER(&tundst, "tundst", settunnel, - "tundst", NULL, NULL, NULL, &command_root.pb_parser); - -struct paddr tunsrc = PADDR_INITIALIZER(&tunsrc, "tunsrc", NULL, - "tunsrc", NULL, NULL, NULL, &tundst.pa_parser); - -static const struct kwinst tunnelkw[] = { - {.k_word = "deletetunnel", .k_exec = deletetunnel, - .k_nextparser = &command_root.pb_parser} - , {.k_word = "tunnel", .k_nextparser = &tunsrc.pa_parser} -}; - -struct pkw tunnel = PKW_INITIALIZER(&tunnel, "tunnel", NULL, NULL, - tunnelkw, __arraycount(tunnelkw), NULL); - -static int -settunnel(prop_dictionary_t env, prop_dictionary_t oenv) -{ - const struct paddr_prefix *srcpfx, *dstpfx; - struct if_laddrreq req; - prop_data_t srcdata, dstdata; - - srcdata = (prop_data_t)prop_dictionary_get(env, "tunsrc"); - dstdata = (prop_data_t)prop_dictionary_get(env, "tundst"); - - if (srcdata == NULL || dstdata == NULL) { - warnx("%s.%d", __func__, __LINE__); - errno = ENOENT; - return -1; - } - - srcpfx = prop_data_data_nocopy(srcdata); - dstpfx = prop_data_data_nocopy(dstdata); - - if (srcpfx->pfx_addr.sa_family != dstpfx->pfx_addr.sa_family) - errx(EXIT_FAILURE, - "source and destination address families do not match"); - - memset(&req, 0, sizeof(req)); - memcpy(&req.addr, &srcpfx->pfx_addr, - MIN(sizeof(req.addr), srcpfx->pfx_addr.sa_len)); - memcpy(&req.dstaddr, &dstpfx->pfx_addr, - MIN(sizeof(req.dstaddr), dstpfx->pfx_addr.sa_len)); - -#ifdef INET6 - if (req.addr.ss_family == AF_INET6) { - struct sockaddr_in6 *s6, *d; - - s6 = (struct sockaddr_in6 *)&req.addr; - d = (struct sockaddr_in6 *)&req.dstaddr; - if (s6->sin6_scope_id != d->sin6_scope_id) { - errx(EXIT_FAILURE, "scope mismatch"); - /* NOTREACHED */ - } - if (IN6_IS_ADDR_MULTICAST(&d->sin6_addr) || - IN6_IS_ADDR_MULTICAST(&s6->sin6_addr)) - errx(EXIT_FAILURE, "tunnel src/dst is multicast"); - /* embed scopeid */ - inet6_putscopeid(s6, INET6_IS_ADDR_LINKLOCAL); - inet6_putscopeid(d, INET6_IS_ADDR_LINKLOCAL); - } -#endif /* INET6 */ - - if (direct_ioctl(env, SIOCSLIFPHYADDR, &req) == -1) - warn("SIOCSLIFPHYADDR"); - return 0; -} - -static int -deletetunnel(prop_dictionary_t env, prop_dictionary_t oenv) -{ - if (indirect_ioctl(env, SIOCDIFPHYADDR, NULL) == -1) - err(EXIT_FAILURE, "SIOCDIFPHYADDR"); - return 0; -} - -static void -tunnel_status(prop_dictionary_t env, prop_dictionary_t oenv) -{ - char dstserv[sizeof(",65535")]; - char srcserv[sizeof(",65535")]; - char psrcaddr[NI_MAXHOST]; - char pdstaddr[NI_MAXHOST]; - const int niflag = Nflag ? 0 : (NI_NUMERICHOST|NI_NUMERICSERV); - struct if_laddrreq req; - const struct afswtch *afp; - - psrcaddr[0] = pdstaddr[0] = '\0'; - - memset(&req, 0, sizeof(req)); - if (direct_ioctl(env, SIOCGLIFPHYADDR, &req) == -1) - return; - afp = lookup_af_bynum(req.addr.ss_family); -#ifdef INET6 - if (req.addr.ss_family == AF_INET6) - inet6_getscopeid((struct sockaddr_in6 *)&req.addr, - INET6_IS_ADDR_LINKLOCAL); -#endif /* INET6 */ - getnameinfo((struct sockaddr *)&req.addr, req.addr.ss_len, - psrcaddr, sizeof(psrcaddr), &srcserv[1], sizeof(srcserv) - 1, - niflag); - -#ifdef INET6 - if (req.dstaddr.ss_family == AF_INET6) - inet6_getscopeid((struct sockaddr_in6 *)&req.dstaddr, - INET6_IS_ADDR_LINKLOCAL); -#endif - getnameinfo((struct sockaddr *)&req.dstaddr, req.dstaddr.ss_len, - pdstaddr, sizeof(pdstaddr), &dstserv[1], sizeof(dstserv) - 1, - niflag); - - srcserv[0] = (strcmp(&srcserv[1], "0") == 0) ? '\0' : ','; - dstserv[0] = (strcmp(&dstserv[1], "0") == 0) ? '\0' : ','; - - printf("\ttunnel %s %s%s --> %s%s\n", afp ? afp->af_name : "???", - psrcaddr, srcserv, pdstaddr, dstserv); -} - -static void -tunnel_usage(prop_dictionary_t env) -{ - fprintf(stderr, - "\t[ [ af ] tunnel src_addr dest_addr ] [ deletetunnel ]\n"); -} - -static void -tunnel_constructor(void) -{ - cmdloop_branch_init(&branch, &tunnel.pk_parser); - register_cmdloop_branch(&branch); - status_func_init(&status, tunnel_status); - usage_func_init(&usage, tunnel_usage); - register_status(&status); - register_usage(&usage); -} diff --git a/sbin/init/Makefile b/sbin/init/Makefile deleted file mode 100644 index 602b5e07a..000000000 --- a/sbin/init/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# $NetBSD: Makefile,v 1.39 2013/07/15 00:18:03 khorben Exp $ -# @(#)Makefile 8.1 (Berkeley) 7/19/93 - -PROG= init -MAN= init.8 -DPADD= ${LIBUTIL} -LDADD= -lutil -CPPFLAGS+= -DMFS_DEV_IF_NO_CONSOLE -DSUPPORT_UTMP -DSUPPORT_UTMPX - -.ifdef INIT_CHROOT -CPPFLAGS+= -DCHROOT -.elifdef SMALLPROG -CPPFLAGS+= -DLETS_GET_SMALL -.else -CPPFLAGS+= -DALTSHELL -DSECURE -DCHROOT -DPADD+= ${LIBCRYPT} -LDADD+= -lcrypt -.endif - -.include diff --git a/sbin/init/NOTES b/sbin/init/NOTES deleted file mode 100644 index ca4eb7797..000000000 --- a/sbin/init/NOTES +++ /dev/null @@ -1,119 +0,0 @@ -$NetBSD: NOTES,v 1.3 2006/04/18 11:40:26 salo Exp $ - -POSIX and init: --------------- - -POSIX.1 does not define 'init' but it mentions it in a few places. - -B.2.2.2, p205 line 873: - - This is part of the extensive 'job control' glossary entry. - This specific reference says that 'init' must by default provide - protection from job control signals to jobs it starts -- - it sets SIGTSTP, SIGTTIN and SIGTTOU to SIG_IGN. - -B.2.2.2, p206 line 889: - - Here is a reference to 'vhangup'. It says, 'POSIX.1 does - not specify how controlling terminal access is affected by - a user logging out (that is, by a controlling process - terminating).' vhangup() is recognized as one way to handle - the problem. I'm not clear what happens in Reno; I have - the impression that when the controlling process terminates, - references to the controlling terminal are converted to - references to a 'dead' vnode. I don't know whether vhangup() - is required. - -B.2.2.2, p206 line 921: - - Orphaned process groups bear indirectly on this issue. A - session leader's process group is considered to be orphaned; - that is, it's immune to job control signals from the terminal. - -B.2.2.2, p233 line 2055: - - 'Historically, the implementation-dependent process that - inherits children whose parents have terminated without - waiting on them is called "init" and has a process ID of 1.' - - It goes on to note that it used to be the case that 'init' - was responsible for sending SIGHUP to the foreground process - group of a tty whose controlling process has exited, using - vhangup(). It is now the responsibility of the kernel to - do this when the controlling process calls _exit(). The - kernel is also responsible for sending SIGCONT to stopped - process groups that become orphaned. This is like old BSD - but entire process groups are signaled instead of individual - processes. - - In general it appears that the kernel now automatically - takes care of orphans, relieving 'init' of any responsibility. - Specifics are listed on the _exit() page (p50). - -On setsid(): ------------ - -It appears that neither getty nor login call setsid(), so init must -do this -- seems reasonable. B.4.3.2 p 248 implies that this is the -way that 'init' should work; it says that setsid() should be called -after forking. - -Process group leaders cannot call setsid() -- another reason to -fork! Of course setsid() causes the current process to become a -process group leader, so we can only call setsid() once. Note that -the controlling terminal acquires the session leader's process -group when opened. - -Controlling terminals: ---------------------- - -B.7.1.1.3 p276: 'POSIX.1 does not specify a mechanism by which to -allocate a controlling terminal. This is normally done by a system -utility (such as 'getty') and is considered ... outside the scope -of POSIX.1.' It goes on to say that historically the first open() -of a tty in a session sets the controlling terminal. P130 has the -full details; nothing particularly surprising. - -The glossary p12 describes a 'controlling process' as the first -process in a session that acquires a controlling terminal. Access -to the terminal from the session is revoked if the controlling -process exits (see p50, in the discussion of process termination). - -Design notes: ------------- - -your generic finite state machine -we are fascist about which signals we elect to receive, - even signals purportedly generated by hardware -handle fatal errors gracefully if possible (we reboot if we goof!!) - if we get a segmentation fault etc., print a message on the console - and spin for a while before rebooting - (this at least decreases the amount of paper consumed :-) -apply hysteresis to rapidly exiting gettys -check wait status of children we reap - don't wait for stopped children -don't use SIGCHILD, it's too expensive - but it may close windows and avoid races, sigh -look for EINTR in case we need to change state -init is responsible for utmp and wtmp maintenance (ick) - maybe now we can consider replacements? maintain them in parallel - init only removes utmp and closes out wtmp entries... - -necessary states and state transitions (gleaned from the man page): - 1: single user shell (with password checking?); on exit, go to 2 - 2: run rc script, on exit 0 check if init.root sysctl != "/", if it - differs then fork + chroot into the value of init.root and run - /etc/rc inside the chroot: on exit 0, go to 3; on exit N (error), - go to 1 (applies also to /etc/rc when init.root == "/") - 3: read ttys file: on completion, go to 4. If we did chroot in - state 2, we chroot after forking each getty to the same dir - (init.root is not re-read) - 4: multi-user operation: on SIGTERM, go to 7; on SIGHUP, go to 5; - on SIGTSTP, go to 6 - 5: clean up mode (re-read ttys file, killing off controlling processes - on lines that are now 'off', starting them on lines newly 'on') - on completion, go to 4 - 6: boring mode (no new sessions); signals as in 4 - 7: death: send SIGHUP to all controlling processes, reap for 30 seconds, - then go to 1 (warn if not all processes died, i.e. wait blocks) -Given the -s flag, we start at state 1; otherwise state 2 diff --git a/sbin/init/init.8 b/sbin/init/init.8 deleted file mode 100644 index 84cad8aaa..000000000 --- a/sbin/init/init.8 +++ /dev/null @@ -1,390 +0,0 @@ -.\" $NetBSD: init.8,v 1.59 2013/10/02 22:07:56 apb Exp $ -.\" -.\" Copyright (c) 1980, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" Donn Seeley at Berkeley Software Design, Inc. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)init.8 8.6 (Berkeley) 5/26/95 -.\" -.Dd October 2, 2013 -.Dt INIT 8 -.Os -.Sh NAME -.Nm init -.Nd process control initialization -.Sh SYNOPSIS -.Nm -.Op Fl s -.Sh DESCRIPTION -The -.Nm -program is the last stage of the boot process. -It normally begins multi-user operation. -.Pp -.Nm -is executed automatically by the kernel, -after the kernel has initialised all devices -and mounted the root file system. -The kernel may try multiple possible paths for -.Nm , -including -.Pa /sbin/init , -.Pa /sbin/oinit , -.Pa /sbin/init.bak , -and -.Pa /rescue/init . -.Pp -The following table describes the state machine used by -.Nm : -.Bl -enum -.It -Single user shell. -If the kernel is booted in single user mode (see -.Xr boothowto 9 ) , -then the kernel will pass the -.Fl s -option to -.Nm -to prevent the system from going multi-user and -to instead execute a single user shell without starting the normal -daemons. -If the kernel is in a secure mode, -.Nm -will downgrade it to securelevel 0 (insecure mode). -The system is then quiescent for maintenance work and may -later be made to go to state 2 (multi-user) by exiting the single-user -shell (with ^D). -.It -Multi-user boot (default operation). -Executes -.Pa /etc/rc -(see -.Xr rc 8 ) . -If this was the first state entered (as opposed to entering here after -state 1), then -.Pa /etc/rc -will be invoked with its first argument being -.Sq autoboot . -If -.Pa /etc/rc -exits with a non-zero (error) exit code, commence single user -operation by giving the super-user a shell on the console by going -to state 1 (single user). -Otherwise, proceed to state 3. -.Pp -If value of the -.Dq init.root -sysctl node is not equal to -.Pa / -at this point, the -.Pa /etc/rc -process will be run inside a -.Xr chroot 2 -indicated by sysctl with the same error handling as above. -.Pp -If the administrator has not set the security level to \-1 -to indicate that the kernel should not run multiuser in secure -mode, and the -.Pa /etc/rc -script has not set a higher level of security -than level 1, then -.Nm -will put the kernel into securelevel mode 1. -See -.Xr rc.conf 5 -and -.Xr secmodel_securelevel 9 -for more information. -.It -Set up ttys as specified in -.Xr ttys 5 . -See below for more information. -On completion, continue to state 4. -If we did chroot in state 2, each -.Xr getty 8 -process will be run in the same -.Xr chroot 2 -path as in 2 (that is, the value of -.Dq init.root -sysctl is not re-read). -.It -Multi-user operation. -Depending upon the signal received, change state appropriately; -on -.Dv SIGTERM , -go to state 7; -on -.Dv SIGHUP , -go to state 5; -on -.Dv SIGTSTP , -go to state 6. -.It -Clean-up mode; re-read -.Xr ttys 5 , -killing off the controlling processes on lines that are now -.Sq off , -and starting processes that are newly -.Sq on . -On completion, go to state 4. -.It -.Sq Boring -mode; no new sessions. -Signals as per state 4. -.It -Shutdown mode. -Send -.Dv SIGHUP -to all controlling processes, reap the processes for 30 seconds, -and then go to state 1 (single user); warning if not all the processes died. -.El -.Pp -If the -.Sq console -entry in the -.Xr ttys 5 -file is marked -.Dq insecure , -then -.Nm -will require that the superuser password be -entered before the system will start a single-user shell. -The password check is skipped if the -.Sq console -is marked as -.Dq secure . -.Pp -It should be noted that while -.Nm -has the ability to start multi-user operation inside a -.Xr chroot 2 -environment, the -.Nm -process itself will always run in the -.Dq original root directory . -This also implies that single-user mode is always started in the original -root, giving the possibility to create multi-user sessions in different -root directories over time. -The -.Dq init.root -sysctl node is fabricated by -.Nm -at startup and re-created any time it's found to be missing. -Type of the node is string capable of holding full pathname, and -is only accessible by the superuser (unless explicitly destroyed -and re-created with different specification). -.Pp -In multi-user operation, -.Nm -maintains -processes for the terminal ports found in the file -.Xr ttys 5 . -.Nm -reads this file, and executes the command found in the second field. -This command is usually -.Xr getty 8 ; -it opens and initializes the tty line and executes the -.Xr login 1 -program. -The -.Xr login 1 -program, when a valid user logs in, executes a shell for that user. -When this shell dies, either because the user logged out or an -abnormal termination occurred (a signal), the -.Nm -program wakes up, deletes the user from the -.Xr utmp 5 -and -.Xr utmpx 5 -files of current users and records the logout in the -.Xr wtmp 5 -and -.Xr wtmpx 5 -files. -The cycle is -then restarted by -.Nm -executing a new -.Xr getty 8 -for the line. -.Pp -Line status (on, off, secure, getty, or window information) -may be changed in the -.Xr ttys 5 -file without a reboot by sending the signal -.Dv SIGHUP -to -.Nm -with the command -.Dq Li "kill \-s HUP 1" . -This is referenced in the table above as state 5. -On receipt of this signal, -.Nm -re-reads the -.Xr ttys 5 -file. -When a line is turned off in -.Xr ttys 5 , -.Nm -will send a -.Dv SIGHUP -signal to the controlling process -for the session associated with the line. -For any lines that were previously turned off in the -.Xr ttys 5 -file and are now on, -.Nm -executes a new -.Xr getty 8 -to enable a new login. -If the getty or window field for a line is changed, -the change takes effect at the end of the current -login session (e.g., the next time -.Nm -starts a process on the line). -If a line is commented out or deleted from -.Xr ttys 5 , -.Nm -will not do anything at all to that line. -However, it will complain that the relationship between lines -in the -.Xr ttys 5 -file and records in the -.Xr utmp 5 -file is out of sync, -so this practice is not recommended. -.Pp -.Nm -will terminate multi-user operations and resume single-user mode -if sent a terminate -.Pq Dv TERM -signal, for example, -.Dq Li "kill \-s TERM 1" . -If there are processes outstanding that are deadlocked (because of -hardware or software failure), -.Nm -will not wait for them all to die (which might take forever), but -will time out after 30 seconds and print a warning message. -.Pp -.Nm -will cease creating new -.Xr getty 8 Ns 's -and allow the system to slowly die away, if it is sent a terminal stop -.Pq Dv TSTP -signal, i.e. -.Dq Li "kill \-s TSTP 1" . -A later hangup will resume full -multi-user operations, or a terminate will start a single user shell. -This hook is used by -.Xr reboot 8 -and -.Xr halt 8 . -.Pp -The role of -.Nm -is so critical that if it dies, the system will reboot itself -automatically. -If, at bootstrap time, the -.Nm -process cannot be located, or exits during its initialisation, -the system will panic with the message -.Dq panic: init died (signal %d, exit %d) . -.Pp -If -.Pa /dev/console -does not exist, -.Nm -will cd to -.Pa /dev -and run -.Dq Li "MAKEDEV -MM init" . -.Xr MAKEDEV 8 -will use -.Xr mount_tmpfs 8 -or -.Xr mount_mfs 8 -to create a memory file system mounted over -.Pa /dev -that contains the standard devices considered necessary to boot the system. -.Sh FILES -.Bl -tag -width /var/log/wtmp{,x} -compact -.It Pa /dev/console -System console device. -.It Pa /dev/tty* -Terminal ports found in -.Xr ttys 5 . -.It Pa /var/run/utmp{,x} -Record of current users on the system. -.It Pa /var/log/wtmp{,x} -Record of all logins and logouts. -.It Pa /etc/ttys -The terminal initialization information file. -.It Pa /etc/rc -System startup commands. -.El -.Sh DIAGNOSTICS -.Bl -diag -.It "getty repeating too quickly on port %s, sleeping" -A process being started to service a line is exiting quickly -each time it is started. -This is often caused by a ringing or noisy terminal line. -.Em "Init will sleep for 10 seconds" , -.Em "then continue trying to start the process" . -.Pp -.It "some processes would not die; ps axl advised." -A process is hung and could not be killed when the system was -shutting down. -This condition is usually caused by a process that is stuck in a -device driver because of a persistent device error condition. -.El -.Sh SEE ALSO -.Xr config 1 , -.Xr kill 1 , -.Xr login 1 , -.Xr sh 1 , -.Xr options 4 , -.Xr ttys 5 , -.Xr getty 8 , -.Xr halt 8 , -.Xr MAKEDEV 8 , -.Xr MAKEDEV.local 8 , -.Xr mount_mfs 8 , -.Xr mount_tmpfs 8 , -.Xr rc 8 , -.Xr reboot 8 , -.Xr rescue 8 , -.Xr shutdown 8 , -.Xr sysctl 8 , -.Xr secmodel_bsd44 9 , -.Xr secmodel_securelevel 9 -.Sh HISTORY -A -.Nm -command appeared in -.At v6 . diff --git a/sbin/init/init.c b/sbin/init/init.c deleted file mode 100644 index c13f4f312..000000000 --- a/sbin/init/init.c +++ /dev/null @@ -1,1902 +0,0 @@ -/* $NetBSD: init.c,v 1.106 2015/06/16 23:18:55 christos Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Donn Seeley at Berkeley Software Design, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1991, 1993\ - The Regents of the University of California. All rights reserved."); -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)init.c 8.2 (Berkeley) 4/28/95"; -#else -__RCSID("$NetBSD: init.c,v 1.106 2015/06/16 23:18:55 christos Exp $"); -#endif -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef SUPPORT_UTMP -#include -#endif -#ifdef SUPPORT_UTMPX -#include -#endif - -#include - -#ifdef SECURE -#include -#endif - -#include "pathnames.h" - -#define XSTR(x) #x -#define STR(x) XSTR(x) - -/* - * Sleep times; used to prevent thrashing. - */ -#define GETTY_SPACING 5 /* N secs minimum getty spacing */ -#define GETTY_SLEEP 30 /* sleep N secs after spacing problem */ -#define WINDOW_WAIT 3 /* wait N secs after starting window */ -#define STALL_TIMEOUT 30 /* wait N secs after warning */ -#define DEATH_WATCH 10 /* wait N secs for procs to die */ - -static const struct timespec dtrtime = {.tv_sec = 0, .tv_nsec = 250000}; - -#if defined(RESCUEDIR) -#define INIT_BSHELL RESCUEDIR "/sh" -#define INIT_MOUNT_MFS RESCUEDIR "/mount_mfs" -#define INIT_PATH RESCUEDIR ":" _PATH_STDPATH -#else -#define INIT_BSHELL _PATH_BSHELL -#define INIT_MOUNT_MFS "/sbin/mount_mfs" -#define INIT_PATH _PATH_STDPATH -#endif - -static void handle(sig_t, ...); -static void delset(sigset_t *, ...); - -static void stall(const char *, ...) __printflike(1, 2); -static void warning(const char *, ...) __printflike(1, 2); -static void emergency(const char *, ...) __printflike(1, 2); -__dead static void disaster(int); - -#if defined(__minix) -static void minixreboot(int); -static void minixpowerdown(int); -#else -static void badsys(int); -#endif /* defined(__minix) */ - -/* - * We really need a recursive typedef... - * The following at least guarantees that the return type of (*state_t)() - * is sufficiently wide to hold a function pointer. - */ -typedef long (*state_func_t)(void); -typedef state_func_t (*state_t)(void); - -#define DEATH 'd' -#define SINGLE_USER 's' -#define RUNCOM 'r' -#define READ_TTYS 't' -#define MULTI_USER 'm' -#define CLEAN_TTYS 'T' -#define CATATONIA 'c' - -static state_func_t single_user(void); -#ifndef LETS_GET_SMALL -static state_func_t runcom(void); -static state_func_t read_ttys(void); -static state_func_t multi_user(void); -static state_func_t clean_ttys(void); -static state_func_t catatonia(void); -static state_func_t death(void); -#endif - -static enum { AUTOBOOT, FASTBOOT } runcom_mode = AUTOBOOT; - -static void transition(state_t); -static void setctty(const char *); - -typedef struct init_session { - int se_index; /* index of entry in ttys file */ - pid_t se_process; /* controlling process */ - struct timeval se_started; /* used to avoid thrashing */ - int se_flags; /* status of session */ -#define SE_SHUTDOWN 0x1 /* session won't be restarted */ -#define SE_PRESENT 0x2 /* session is in /etc/ttys */ - char *se_device; /* filename of port */ - char *se_getty; /* what to run on that port */ - char **se_getty_argv; /* pre-parsed argument array */ - char *se_window; /* window system (started only once) */ - char **se_window_argv; /* pre-parsed argument array */ - struct init_session *se_prev; - struct init_session *se_next; -} session_t; - -static void collect_child(pid_t, int); -static int clang; -static void transition_handler(int); -static void alrm_handler(int); -static int has_securelevel(void); -static int securelevel_present; - -#ifndef LETS_GET_SMALL -static int do_setttyent(void); -static void start_window_system(session_t *); -static char **construct_argv(char *); -static int setupargv(session_t *, struct ttyent *); -static pid_t start_getty(session_t *); -static void free_session(session_t *); -static session_t *new_session(session_t *, int, struct ttyent *); -static session_t *sessions; -static void setsecuritylevel(int); -static int getsecuritylevel(void); -static int start_session_db(void); -static void add_session(session_t *); -static void del_session(session_t *); -static session_t *find_session(pid_t); -static DB *session_db; -static state_t requested_transition = runcom; - -static void clear_session_logs(session_t *, int); -static state_func_t runetcrc(int); -#ifdef SUPPORT_UTMPX -static struct timeval boot_time; -static state_t current_state = death; -static void session_utmpx(const session_t *, int); -static void make_utmpx(const char *, const char *, int, pid_t, - const struct timeval *, int); -static char get_runlevel(const state_t); -static void utmpx_set_runlevel(char, char); -#endif - -#ifdef CHROOT -static int did_multiuser_chroot = 0; -static char rootdir[PATH_MAX]; -static int shouldchroot(void); -static int createsysctlnode(void); -#endif /* CHROOT */ - -#else /* LETS_GET_SMALL */ -static state_t requested_transition = single_user; -#endif /* !LETS_GET_SMALL */ - -#ifdef MFS_DEV_IF_NO_CONSOLE - -static int mfs_dev(void); - -#endif - -/* - * The mother of all processes. - */ -int -main(int argc, char **argv) -{ - struct sigaction sa; - sigset_t mask; -#ifndef LETS_GET_SMALL - int c; - -#ifdef SUPPORT_UTMPX - (void)gettimeofday(&boot_time, NULL); -#endif /* SUPPORT_UTMPX */ - - /* Dispose of random users. */ - if (getuid() != 0) { - errno = EPERM; - err(1, NULL); - } - - /* System V users like to reexec init. */ - if (getpid() != 1) - errx(1, "already running"); -#endif - - /* - * Create an initial session. - */ - if (setsid() < 0) - warn("initial setsid() failed"); - - /* - * Establish an initial user so that programs running - * single user do not freak out and die (like passwd). - */ -#if !defined(__minix) - if (setlogin("root") < 0) - warn("setlogin() failed"); -#endif /* !defined(__minix) */ - - -#ifdef MFS_DEV_IF_NO_CONSOLE - if (mfs_dev() == -1) - requested_transition = single_user; -#endif - -#ifndef LETS_GET_SMALL - /* - * Note that this does NOT open a file... - * Does 'init' deserve its own facility number? - */ - openlog("init", LOG_CONS, LOG_AUTH); -#endif /* LETS_GET_SMALL */ - - -#ifndef LETS_GET_SMALL - /* - * This code assumes that we always get arguments through flags, - * never through bits set in some random machine register. - */ - while ((c = getopt(argc, argv, "sf")) != -1) - switch (c) { - case 's': - requested_transition = single_user; - break; - case 'f': - runcom_mode = FASTBOOT; - break; - default: - warning("unrecognized flag `%c'", c); - break; - } - - if (optind != argc) - warning("ignoring excess arguments"); -#else /* LETS_GET_SMALL */ - requested_transition = single_user; -#endif /* LETS_GET_SMALL */ - - /* - * We catch or block signals rather than ignore them, - * so that they get reset on exec. - */ -#if !defined(__minix) - handle(badsys, SIGSYS, 0); - handle(disaster, SIGABRT, SIGFPE, SIGILL, SIGSEGV, - SIGBUS, SIGXCPU, SIGXFSZ, 0); -#else - handle(minixreboot, SIGABRT, 0); - handle(minixpowerdown, SIGUSR1, 0); - handle(disaster, SIGFPE, SIGILL, SIGSEGV, SIGBUS, 0); -#endif /* !defined(__minix) */ - handle(transition_handler, SIGHUP, SIGTERM, SIGTSTP, 0); - handle(alrm_handler, SIGALRM, 0); - (void)sigfillset(&mask); -#if !defined(__minix) - delset(&mask, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS, - SIGXCPU, SIGXFSZ, SIGHUP, SIGTERM, SIGTSTP, SIGALRM, 0); -#else - delset(&mask, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, - SIGHUP, SIGTERM, SIGTSTP, SIGALRM, 0); -#endif /* !defined(__minix) */ - (void)sigprocmask(SIG_SETMASK, &mask, NULL); - (void)sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = SIG_IGN; - (void)sigaction(SIGTTIN, &sa, NULL); - (void)sigaction(SIGTTOU, &sa, NULL); - - /* - * Paranoia. - */ - (void)close(0); - (void)close(1); - (void)close(2); - -#if !defined(LETS_GET_SMALL) && defined(CHROOT) - /* Create "init.root" sysctl node. */ - (void)createsysctlnode(); -#endif /* !LETS_GET_SMALL && CHROOT*/ - - /* - * Securelevel might not be supported by the kernel. Query for it, and - * set a variable indicating whether we should attempt anything with it - * or not. - */ - securelevel_present = has_securelevel(); - - /* - * Start the state machine. - */ - transition(requested_transition); - - /* - * Should never reach here. - */ - return 1; -} - -/* - * Associate a function with a signal handler. - */ -static void -handle(sig_t handler, ...) -{ - int sig; - struct sigaction sa; - sigset_t mask_everything; - va_list ap; - - va_start(ap, handler); - - sa.sa_handler = handler; - (void)sigfillset(&mask_everything); - - while ((sig = va_arg(ap, int)) != 0) { - sa.sa_mask = mask_everything; - /* XXX SA_RESTART? */ - sa.sa_flags = sig == SIGCHLD ? SA_NOCLDSTOP : 0; - (void)sigaction(sig, &sa, NULL); - } - va_end(ap); -} - -/* - * Delete a set of signals from a mask. - */ -static void -delset(sigset_t *maskp, ...) -{ - int sig; - va_list ap; - - va_start(ap, maskp); - - while ((sig = va_arg(ap, int)) != 0) - (void)sigdelset(maskp, sig); - va_end(ap); -} - -#if 0 /* Enable to get error messages from init ! */ -#define vsyslog(level, fmt, ap) print_console(level, fmt, ap) -#define closelog() - -static void -print_console(int level, const char *message, va_list ap) -{ - /* - * XXX: syslog seems to just plain not work in console-only - * XXX: situation... that should be fixed. Let's leave this - * XXX: note + code here in case someone gets in trouble and - * XXX: wants to debug. -- Jachym Holecek - */ - char errbuf[1024]; - int fd, len; - - /* We can't do anything on errors, anyway... */ - fd = open(_PATH_CONSOLE, O_WRONLY); - if (fd == -1) - return ; - - /* %m will get lost... */ - len = vsnprintf(errbuf, sizeof(errbuf), message, ap); - (void)write(fd, (void *)errbuf, len); - (void)close(fd); -} -#endif - -/* - * Log a message and sleep for a while (to give someone an opportunity - * to read it and to save log or hardcopy output if the problem is chronic). - * NB: should send a message to the session logger to avoid blocking. - */ -static void -stall(const char *message, ...) -{ - va_list ap; - - va_start(ap, message); - vsyslog(LOG_ALERT, message, ap); - va_end(ap); - closelog(); - (void)sleep(STALL_TIMEOUT); -} - -/* - * Like stall(), but doesn't sleep. - * If cpp had variadic macros, the two functions could be #defines for another. - * NB: should send a message to the session logger to avoid blocking. - */ -static void -warning(const char *message, ...) -{ - va_list ap; - - va_start(ap, message); - vsyslog(LOG_ALERT, message, ap); - va_end(ap); - closelog(); -} - -/* - * Log an emergency message. - * NB: should send a message to the session logger to avoid blocking. - */ -static void -emergency(const char *message, ...) -{ - va_list ap; - - va_start(ap, message); - vsyslog(LOG_EMERG, message, ap); - va_end(ap); - closelog(); -} - -#if !defined(__minix) -/* - * Catch a SIGSYS signal. - * - * These may arise if a system does not support sysctl. - * We tolerate up to 25 of these, then throw in the towel. - */ -static void -badsys(int sig) -{ - static int badcount = 0; - - if (badcount++ < 25) - return; - disaster(sig); -} -#endif /* !defined(__minix) */ - -/* - * Catch an unexpected signal. - */ -static void -disaster(int sig) -{ - - emergency("fatal signal: %s", strsignal(sig)); - (void)sleep(STALL_TIMEOUT); - _exit(sig); /* reboot */ -} - -#if defined(__minix) -/* - * controlled reboot - minix tradition, SIGABRT by tty - */ -static void -minixreboot(int sig) -{ - if(fork() == 0) { - (void)execl("/sbin/shutdown", - "shutdown", "-r", "now", "CTRL-ALT_DEL", NULL); - _exit(1); - } -} - -/* - * controlled powerdown - */ -static void -minixpowerdown(int sig) -{ - if(fork() == 0) { - (void)execl("/sbin/shutdown", - "shutdown", "-p", "now", "CTRL-ALT_DEL", NULL); - _exit(1); - } -} -#endif /* defined(__minix) */ - -/* - * Check if securelevel is present. - */ -static int -has_securelevel(void) -{ -#ifdef KERN_SECURELVL - int name[2], curlevel; - size_t len; - - name[0] = CTL_KERN; - name[1] = KERN_SECURELVL; - len = sizeof curlevel; - if (sysctl(name, 2, &curlevel, &len, NULL, 0) == -1) { - /* If it doesn't exist, it's okay. */ - if (errno == ENOENT) - return 0; - } - return 1; -#else - return 0; -#endif -} - -/* - * Get the security level of the kernel. - */ -static int -getsecuritylevel(void) -{ -#ifdef KERN_SECURELVL - int name[2], curlevel; - size_t len; - - if (!securelevel_present) - return -1; - - name[0] = CTL_KERN; - name[1] = KERN_SECURELVL; - len = sizeof curlevel; - if (sysctl(name, 2, &curlevel, &len, NULL, 0) == -1) { - emergency("cannot get kernel security level: %m"); - return -1; - } - return curlevel; -#else - return -1; -#endif -} - -/* - * Set the security level of the kernel. - */ -static void -setsecuritylevel(int newlevel) -{ -#ifdef KERN_SECURELVL - int name[2], curlevel; - - if (!securelevel_present) - return; - - curlevel = getsecuritylevel(); - if (newlevel == curlevel) - return; - name[0] = CTL_KERN; - name[1] = KERN_SECURELVL; - if (sysctl(name, 2, NULL, NULL, &newlevel, sizeof newlevel) == -1) { - emergency("cannot change kernel security level from" - " %d to %d: %m", curlevel, newlevel); - return; - } -#ifdef SECURE - warning("kernel security level changed from %d to %d", - curlevel, newlevel); -#endif -#endif -} - -/* - * Change states in the finite state machine. - * The initial state is passed as an argument. - */ -static void -transition(state_t s) -{ - - if (s == NULL) - return; - for (;;) { -#ifdef SUPPORT_UTMPX -#ifndef LETS_GET_SMALL - utmpx_set_runlevel(get_runlevel(current_state), - get_runlevel(s)); - current_state = s; -#endif -#endif - s = (state_t)(*s)(); - } -} - -#ifndef LETS_GET_SMALL -/* - * Close out the accounting files for a login session. - * NB: should send a message to the session logger to avoid blocking. - */ -static void -clear_session_logs(session_t *sp, int status) -{ -#if defined(SUPPORT_UTMP) || defined(SUPPORT_UTMPX) - char *line = sp->se_device + sizeof(_PATH_DEV) - 1; -#endif - -#ifdef SUPPORT_UTMPX - if (logoutx(line, status, DEAD_PROCESS)) - logwtmpx(line, "", "", status, DEAD_PROCESS); -#endif -#ifdef SUPPORT_UTMP - if (logout(line)) - logwtmp(line, "", ""); -#endif -} -#endif - -/* - * Start a session and allocate a controlling terminal. - * Only called by children of init after forking. - */ -static void -setctty(const char *name) -{ - int fd; - -#if !defined(__minix) - (void)revoke(name); -#else - if (setsid() < 0) - warn("child setsid() failed"); -#endif /* !defined(__minix) */ - (void)nanosleep(&dtrtime, NULL); /* leave DTR low for a bit */ - if ((fd = open(name, O_RDWR)) == -1) { - stall("can't open %s: %m", name); - _exit(1); - } - if (login_tty(fd) == -1) { - stall("can't get %s for controlling terminal: %m", name); - _exit(2); - } -} - -/* - * Bring the system up single user. - */ -static state_func_t -single_user(void) -{ - pid_t pid, wpid; - int status; - int from_securitylevel; - sigset_t mask; - struct sigaction sa, satstp, sahup; -#ifdef ALTSHELL - const char *shell = INIT_BSHELL; -#endif - const char *argv[2]; -#ifdef SECURE - struct ttyent *typ; - struct passwd *pp; - char *clear, *password; -#endif -#ifdef ALTSHELL - char altshell[128]; -#endif /* ALTSHELL */ - -#if !defined(LETS_GET_SMALL) && defined(CHROOT) - /* Clear previous idea, just in case. */ - did_multiuser_chroot = 0; -#endif /* !LETS_GET_SMALL && CHROOT */ - - /* - * If the kernel is in secure mode, downgrade it to insecure mode. - */ - from_securitylevel = getsecuritylevel(); - if (from_securitylevel > 0) - setsecuritylevel(0); - - (void)sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = SIG_IGN; - (void)sigaction(SIGTSTP, &sa, &satstp); - (void)sigaction(SIGHUP, &sa, &sahup); - if ((pid = fork()) == 0) { - /* - * Start the single user session. - */ - if (access(_PATH_CONSTTY, F_OK) == 0) - setctty(_PATH_CONSTTY); - else - setctty(_PATH_CONSOLE); - -#ifdef SECURE - /* - * Check the root password. - * We don't care if the console is 'on' by default; - * it's the only tty that can be 'off' and 'secure'. - */ - typ = getttynam("console"); - pp = getpwnam("root"); - if (typ && (from_securitylevel >=2 || (typ->ty_status - & TTY_SECURE) == 0) && pp && *pp->pw_passwd != '\0') { - (void)fprintf(stderr, - "Enter root password, or ^D to go multi-user\n"); - for (;;) { - clear = getpass("Password:"); - if (clear == 0 || *clear == '\0') - _exit(0); - password = crypt(clear, pp->pw_passwd); - (void)memset(clear, 0, _PASSWORD_LEN); - if (strcmp(password, pp->pw_passwd) == 0) - break; - warning("single-user login failed"); - } - } - (void)endttyent(); - endpwent(); -#endif /* SECURE */ - -#ifdef ALTSHELL - (void)fprintf(stderr, - "Enter pathname of shell or RETURN for %s: ", shell); - if (fgets(altshell, sizeof(altshell), stdin) == NULL) { - altshell[0] = '\0'; - } else { - /* nuke \n */ - char *p; - - if ((p = strchr(altshell, '\n')) != NULL) - *p = '\0'; - } - - if (altshell[0]) - shell = altshell; -#endif /* ALTSHELL */ - - /* - * Unblock signals. - * We catch all the interesting ones, - * and those are reset to SIG_DFL on exec. - */ - (void)sigemptyset(&mask); - (void)sigprocmask(SIG_SETMASK, &mask, NULL); - - /* - * Fire off a shell. - * If the default one doesn't work, try the Bourne shell. - */ - argv[0] = "-sh"; - argv[1] = 0; - (void)setenv("PATH", INIT_PATH, 1); -#ifdef ALTSHELL - if (altshell[0]) - argv[0] = altshell; - (void)execv(shell, __UNCONST(argv)); - emergency("can't exec `%s' for single user: %m", shell); - argv[0] = "-sh"; -#endif /* ALTSHELL */ - (void)execv(INIT_BSHELL, __UNCONST(argv)); - emergency("can't exec `%s' for single user: %m", INIT_BSHELL); - (void)sleep(STALL_TIMEOUT); - _exit(3); - } - - if (pid == -1) { - /* - * We are seriously hosed. Do our best. - */ - emergency("can't fork single-user shell: %m, trying again"); - while (waitpid(-1, NULL, WNOHANG) > 0) - continue; - (void)sigaction(SIGTSTP, &satstp, NULL); - (void)sigaction(SIGHUP, &sahup, NULL); - return (state_func_t)single_user; - } - - requested_transition = 0; - do { - if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1) - collect_child(wpid, status); - if (wpid == -1) { - if (errno == EINTR) - continue; - warning("wait for single-user shell failed: %m; " - "restarting"); - return (state_func_t)single_user; - } - if (wpid == pid && WIFSTOPPED(status)) { - warning("shell stopped, restarting"); - (void)kill(pid, SIGCONT); - wpid = -1; - } - } while (wpid != pid && !requested_transition); - - if (requested_transition) { - (void)sigaction(SIGTSTP, &satstp, NULL); - (void)sigaction(SIGHUP, &sahup, NULL); - return (state_func_t)requested_transition; - } - - if (WIFSIGNALED(status)) { - if (WTERMSIG(status) == SIGKILL) { - /* executed /sbin/reboot; wait for the end quietly */ - sigset_t s; - - (void)sigfillset(&s); - for (;;) - (void)sigsuspend(&s); - } else { - warning("single user shell terminated (%x), restarting", - status); - (void)sigaction(SIGTSTP, &satstp, NULL); - (void)sigaction(SIGHUP, &sahup, NULL); - return (state_func_t)single_user; - } - } - - runcom_mode = FASTBOOT; - (void)sigaction(SIGTSTP, &satstp, NULL); - (void)sigaction(SIGHUP, &sahup, NULL); -#ifndef LETS_GET_SMALL - return (state_func_t)runcom; -#else /* LETS_GET_SMALL */ - return (state_func_t)single_user; -#endif /* LETS_GET_SMALL */ -} - -#ifndef LETS_GET_SMALL - -/* ARGSUSED */ -static state_func_t -runetcrc(int trychroot) -{ - pid_t pid, wpid; - int status; - const char *argv[4]; - struct sigaction sa; - - switch ((pid = fork())) { - case 0: - (void)sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = SIG_IGN; - (void)sigaction(SIGTSTP, &sa, NULL); - (void)sigaction(SIGHUP, &sa, NULL); - - setctty(_PATH_CONSOLE); - - argv[0] = "sh"; - argv[1] = _PATH_RUNCOM; - argv[2] = (runcom_mode == AUTOBOOT ? "autoboot" : 0); - argv[3] = 0; - - (void)sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL); - -#ifdef CHROOT - if (trychroot) - if (chroot(rootdir) != 0) { - warning("failed to chroot to `%s': %m", - rootdir); - _exit(4); /* force single user mode */ - } -#endif /* CHROOT */ - - (void)execv(INIT_BSHELL, __UNCONST(argv)); - stall("can't exec `%s' for `%s': %m", INIT_BSHELL, _PATH_RUNCOM); - _exit(5); /* force single user mode */ - /*NOTREACHED*/ - case -1: - emergency("can't fork for `%s' on `%s': %m", INIT_BSHELL, - _PATH_RUNCOM); - while (waitpid(-1, NULL, WNOHANG) > 0) - continue; - (void)sleep(STALL_TIMEOUT); - return (state_func_t)single_user; - default: - break; - } - - /* - * Copied from single_user(). This is a bit paranoid. - */ - do { - if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1) - collect_child(wpid, status); - if (wpid == -1) { - if (errno == EINTR) - continue; - warning("wait for `%s' on `%s' failed: %m; going to " - "single user mode", INIT_BSHELL, _PATH_RUNCOM); - return (state_func_t)single_user; - } - if (wpid == pid && WIFSTOPPED(status)) { - warning("`%s' on `%s' stopped, restarting", - INIT_BSHELL, _PATH_RUNCOM); - (void)kill(pid, SIGCONT); - wpid = -1; - } - } while (wpid != pid); - - if (WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM && - requested_transition == catatonia) { - /* /etc/rc executed /sbin/reboot; wait for the end quietly */ - sigset_t s; - - (void)sigfillset(&s); - for (;;) - (void)sigsuspend(&s); - } - - if (!WIFEXITED(status)) { - warning("`%s' on `%s' terminated abnormally, going to " - "single user mode", INIT_BSHELL, _PATH_RUNCOM); - return (state_func_t)single_user; - } - - if (WEXITSTATUS(status)) - return (state_func_t)single_user; - - return (state_func_t)read_ttys; -} - -/* - * Run the system startup script. - */ -static state_func_t -runcom(void) -{ - state_func_t next_step; - - /* Run /etc/rc and choose next state depending on the result. */ - next_step = runetcrc(0); - if (next_step != (state_func_t)read_ttys) - return (state_func_t)next_step; - -#ifdef CHROOT - /* - * If init.root sysctl does not point to "/", we'll chroot and run - * The Real(tm) /etc/rc now. Global variable rootdir will tell us - * where to go. - */ - if (shouldchroot()) { - next_step = runetcrc(1); - if (next_step != (state_func_t)read_ttys) - return (state_func_t)next_step; - - did_multiuser_chroot = 1; - } else { - did_multiuser_chroot = 0; - } -#endif /* CHROOT */ - - /* - * Regardless of whether in chroot or not, we booted successfuly. - * It's time to spawn gettys (ie. next_step's value at this point). - */ - runcom_mode = AUTOBOOT; /* the default */ - /* NB: should send a message to the session logger to avoid blocking. */ -#ifdef SUPPORT_UTMPX - logwtmpx("~", "reboot", "", 0, INIT_PROCESS); -#endif -#ifdef SUPPORT_UTMP - logwtmp("~", "reboot", ""); -#endif - return (state_func_t)read_ttys; -} - -/* - * Open the session database. - * - * NB: We could pass in the size here; is it necessary? - */ -static int -start_session_db(void) -{ - - if (session_db && (*session_db->close)(session_db)) - emergency("session database close: %m"); - if ((session_db = dbopen(NULL, O_RDWR, 0, DB_HASH, NULL)) == 0) { - emergency("session database open: %m"); - return 1; - } - return 0; - -} - -/* - * Add a new login session. - */ -static void -add_session(session_t *sp) -{ - DBT key; - DBT data; - - if (session_db == NULL) - return; - - key.data = &sp->se_process; - key.size = sizeof sp->se_process; - data.data = &sp; - data.size = sizeof sp; - - if ((*session_db->put)(session_db, &key, &data, 0)) - emergency("insert %d: %m", sp->se_process); -#ifdef SUPPORT_UTMPX - session_utmpx(sp, 1); -#endif -} - -/* - * Delete an old login session. - */ -static void -del_session(session_t *sp) -{ - DBT key; - - key.data = &sp->se_process; - key.size = sizeof sp->se_process; - - if ((*session_db->del)(session_db, &key, 0)) - emergency("delete %d: %m", sp->se_process); -#ifdef SUPPORT_UTMPX - session_utmpx(sp, 0); -#endif -} - -/* - * Look up a login session by pid. - */ -static session_t * -find_session(pid_t pid) -{ - DBT key; - DBT data; - session_t *ret; - - if (session_db == NULL) - return NULL; - - key.data = &pid; - key.size = sizeof pid; - if ((*session_db->get)(session_db, &key, &data, 0) != 0) - return 0; - (void)memmove(&ret, data.data, sizeof(ret)); - return ret; -} - -/* - * Construct an argument vector from a command line. - */ -static char ** -construct_argv(char *command) -{ - int argc = 0; - char **argv = malloc(((strlen(command) + 1) / 2 + 1) * sizeof (char *)); - static const char separators[] = " \t"; - - if (argv == NULL) - return NULL; - - if ((argv[argc++] = strtok(command, separators)) == 0) { - free(argv); - return NULL; - } - while ((argv[argc++] = strtok(NULL, separators)) != NULL) - continue; - return argv; -} - -/* - * Deallocate a session descriptor. - */ -static void -free_session(session_t *sp) -{ - - free(sp->se_device); - if (sp->se_getty) { - free(sp->se_getty); - free(sp->se_getty_argv); - } - if (sp->se_window) { - free(sp->se_window); - free(sp->se_window_argv); - } - free(sp); -} - -/* - * Allocate a new session descriptor. - */ -static session_t * -new_session(session_t *sprev, int session_index, struct ttyent *typ) -{ - session_t *sp; - - if ((typ->ty_status & TTY_ON) == 0 || typ->ty_name == NULL || - typ->ty_getty == NULL) - return NULL; - - sp = malloc(sizeof (session_t)); - if (sp == NULL) - return NULL; - (void)memset(sp, 0, sizeof *sp); - - sp->se_flags = SE_PRESENT; - sp->se_index = session_index; - - (void)asprintf(&sp->se_device, "%s%s", _PATH_DEV, typ->ty_name); - if (!sp->se_device) { - free(sp); - return NULL; - } - - if (setupargv(sp, typ) == 0) { - free_session(sp); - return NULL; - } - - sp->se_next = NULL; - if (sprev == NULL) { - sessions = sp; - sp->se_prev = NULL; - } else { - sprev->se_next = sp; - sp->se_prev = sprev; - } - - return sp; -} - -/* - * Calculate getty and if useful window argv vectors. - */ -static int -setupargv(session_t *sp, struct ttyent *typ) -{ - - if (sp->se_getty) { - free(sp->se_getty); - free(sp->se_getty_argv); - } - (void)asprintf(&sp->se_getty, "%s %s", typ->ty_getty, typ->ty_name); - if (!sp->se_getty) - return 0; - sp->se_getty_argv = construct_argv(sp->se_getty); - if (sp->se_getty_argv == NULL) { - warning("can't parse getty for port `%s'", sp->se_device); - free(sp->se_getty); - sp->se_getty = NULL; - return 0; - } - if (typ->ty_window) { - if (sp->se_window) - free(sp->se_window); - sp->se_window = strdup(typ->ty_window); - sp->se_window_argv = construct_argv(sp->se_window); - if (sp->se_window_argv == NULL) { - warning("can't parse window for port `%s'", - sp->se_device); - free(sp->se_window); - sp->se_window = NULL; - return 0; - } - } - return 1; -} - -/* - * Walk the list of ttys and create sessions for each active line. - */ -static state_func_t -read_ttys(void) -{ - int session_index = 0; - session_t *sp, *snext; - struct ttyent *typ; - -#ifdef SUPPORT_UTMPX - if (sessions == NULL) { - struct stat st; - - make_utmpx("", BOOT_MSG, BOOT_TIME, 0, &boot_time, 0); - - /* - * If wtmpx is not empty, pick the down time from there - */ - if (stat(_PATH_WTMPX, &st) != -1 && st.st_size != 0) { - struct timeval down_time; - - TIMESPEC_TO_TIMEVAL(&down_time, - st.st_atime > st.st_mtime ? - &st.st_atimespec : &st.st_mtimespec); - make_utmpx("", DOWN_MSG, DOWN_TIME, 0, &down_time, 0); - } - } -#endif - /* - * Destroy any previous session state. - * There shouldn't be any, but just in case... - */ - for (sp = sessions; sp; sp = snext) { -#ifndef LETS_GET_SMALL - if (sp->se_process) - clear_session_logs(sp, 0); -#endif - snext = sp->se_next; - free_session(sp); - } - sessions = NULL; - - if (start_session_db()) { - warning("start_session_db failed, death"); -#ifdef CHROOT - /* If /etc/rc ran in chroot, we want to kill any survivors. */ - if (did_multiuser_chroot) - return (state_func_t)death; - else -#endif /* CHROOT */ - return (state_func_t)single_user; - } - - (void)do_setttyent(); - - /* - * Allocate a session entry for each active port. - * Note that sp starts at 0. - */ - while ((typ = getttyent()) != NULL) - if ((snext = new_session(sp, ++session_index, typ)) != NULL) - sp = snext; - (void)endttyent(); - - return (state_func_t)multi_user; -} - -/* - * Start a window system running. - */ -static void -start_window_system(session_t *sp) -{ - pid_t pid; - sigset_t mask; - - if ((pid = fork()) == -1) { - emergency("can't fork for window system on port `%s': %m", - sp->se_device); - /* hope that getty fails and we can try again */ - return; - } - - if (pid) - return; - - (void)sigemptyset(&mask); - (void)sigprocmask(SIG_SETMASK, &mask, NULL); - - if (setsid() < 0) - emergency("setsid failed (window): %m"); - - (void)execv(sp->se_window_argv[0], sp->se_window_argv); - stall("can't exec window system `%s' for port `%s': %m", - sp->se_window_argv[0], sp->se_device); - _exit(6); -} - -/* - * Start a login session running. - */ -static pid_t -start_getty(session_t *sp) -{ - pid_t pid; - sigset_t mask; - time_t current_time = time(NULL); - - /* - * fork(), not vfork() -- we can't afford to block. - */ - if ((pid = fork()) == -1) { - emergency("can't fork for getty on port `%s': %m", - sp->se_device); - return -1; - } - - if (pid) - return pid; - -#ifdef CHROOT - /* If /etc/rc did proceed inside chroot, we have to try as well. */ - if (did_multiuser_chroot) - if (chroot(rootdir) != 0) { - stall("can't chroot getty `%s' inside `%s': %m", - sp->se_getty_argv[0], rootdir); - _exit(7); - } -#endif /* CHROOT */ - - if (current_time > sp->se_started.tv_sec && - current_time - sp->se_started.tv_sec < GETTY_SPACING) { - warning("getty repeating too quickly on port `%s', sleeping", - sp->se_device); - (void)sleep(GETTY_SLEEP); - } - - if (sp->se_window) { - start_window_system(sp); - (void)sleep(WINDOW_WAIT); - } - - (void)sigemptyset(&mask); - (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0); - - (void)execv(sp->se_getty_argv[0], sp->se_getty_argv); - stall("can't exec getty `%s' for port `%s': %m", - sp->se_getty_argv[0], sp->se_device); - _exit(8); - /*NOTREACHED*/ -} -#ifdef SUPPORT_UTMPX -static void -session_utmpx(const session_t *sp, int add) -{ - const char *name = sp->se_getty ? sp->se_getty : - (sp->se_window ? sp->se_window : ""); - const char *line = sp->se_device + sizeof(_PATH_DEV) - 1; - - make_utmpx(name, line, add ? LOGIN_PROCESS : DEAD_PROCESS, - sp->se_process, &sp->se_started, sp->se_index); -} - -static void -make_utmpx(const char *name, const char *line, int type, pid_t pid, - const struct timeval *tv, int session) -{ - struct utmpx ut; - const char *eline; - - (void)memset(&ut, 0, sizeof(ut)); - (void)strlcpy(ut.ut_name, name, sizeof(ut.ut_name)); - ut.ut_type = type; - (void)strlcpy(ut.ut_line, line, sizeof(ut.ut_line)); - ut.ut_pid = pid; - if (tv) - ut.ut_tv = *tv; - else - (void)gettimeofday(&ut.ut_tv, NULL); - ut.ut_session = session; - - eline = line + strlen(line); - if ((size_t)(eline - line) >= sizeof(ut.ut_id)) - line = eline - sizeof(ut.ut_id); - (void)strncpy(ut.ut_id, line, sizeof(ut.ut_id)); - - if (pututxline(&ut) == NULL) - warning("can't add utmpx record for `%s': %m", ut.ut_line); - endutxent(); -} - -static char -get_runlevel(const state_t s) -{ - if (s == (state_t)single_user) - return SINGLE_USER; - if (s == (state_t)runcom) - return RUNCOM; - if (s == (state_t)read_ttys) - return READ_TTYS; - if (s == (state_t)multi_user) - return MULTI_USER; - if (s == (state_t)clean_ttys) - return CLEAN_TTYS; - if (s == (state_t)catatonia) - return CATATONIA; - return DEATH; -} - -static void -utmpx_set_runlevel(char old, char new) -{ - struct utmpx ut; - - /* - * Don't record any transitions until we did the first transition - * to read ttys, which is when we are guaranteed to have a read-write - * /var. Perhaps use a different variable for this? - */ - if (sessions == NULL) - return; - - (void)memset(&ut, 0, sizeof(ut)); - (void)snprintf(ut.ut_line, sizeof(ut.ut_line), RUNLVL_MSG, new); - ut.ut_type = RUN_LVL; - (void)gettimeofday(&ut.ut_tv, NULL); - ut.ut_exit.e_exit = old; - ut.ut_exit.e_termination = new; - if (pututxline(&ut) == NULL) - warning("can't add utmpx record for `runlevel': %m"); - endutxent(); -} -#endif /* SUPPORT_UTMPX */ - -#endif /* LETS_GET_SMALL */ - -/* - * Collect exit status for a child. - * If an exiting login, start a new login running. - */ -static void -collect_child(pid_t pid, int status) -{ -#ifndef LETS_GET_SMALL - session_t *sp, *sprev, *snext; - - if (! sessions) - return; - - if ((sp = find_session(pid)) == NULL) - return; - - clear_session_logs(sp, status); - del_session(sp); - sp->se_process = 0; - - if (sp->se_flags & SE_SHUTDOWN) { - if ((sprev = sp->se_prev) != NULL) - sprev->se_next = sp->se_next; - else - sessions = sp->se_next; - if ((snext = sp->se_next) != NULL) - snext->se_prev = sp->se_prev; - free_session(sp); - return; - } - - if ((pid = start_getty(sp)) == -1) { - /* serious trouble */ - requested_transition = clean_ttys; - return; - } - - sp->se_process = pid; - (void)gettimeofday(&sp->se_started, NULL); - add_session(sp); -#endif /* LETS_GET_SMALL */ -} - -/* - * Catch a signal and request a state transition. - */ -static void -transition_handler(int sig) -{ - - switch (sig) { -#ifndef LETS_GET_SMALL - case SIGHUP: - requested_transition = clean_ttys; - break; - case SIGTERM: - requested_transition = death; - break; - case SIGTSTP: - requested_transition = catatonia; - break; -#endif /* LETS_GET_SMALL */ - default: - requested_transition = 0; - break; - } -} - -#ifndef LETS_GET_SMALL -/* - * Take the system multiuser. - */ -static state_func_t -multi_user(void) -{ - pid_t pid; - int status; - session_t *sp; - - requested_transition = 0; - - /* - * If the administrator has not set the security level to -1 - * to indicate that the kernel should not run multiuser in secure - * mode, and the run script has not set a higher level of security - * than level 1, then put the kernel into secure mode. - */ - if (getsecuritylevel() == 0) - setsecuritylevel(1); - - for (sp = sessions; sp; sp = sp->se_next) { - if (sp->se_process) - continue; - if ((pid = start_getty(sp)) == -1) { - /* serious trouble */ - requested_transition = clean_ttys; - break; - } - sp->se_process = pid; - (void)gettimeofday(&sp->se_started, NULL); - add_session(sp); - } - - while (!requested_transition) - if ((pid = waitpid(-1, &status, 0)) != -1) - collect_child(pid, status); - - return (state_func_t)requested_transition; -} - -/* - * This is an n-squared algorithm. We hope it isn't run often... - */ -static state_func_t -clean_ttys(void) -{ - session_t *sp, *sprev; - struct ttyent *typ; - int session_index = 0; - int devlen; - - for (sp = sessions; sp; sp = sp->se_next) - sp->se_flags &= ~SE_PRESENT; - - (void)do_setttyent(); - - devlen = sizeof(_PATH_DEV) - 1; - while ((typ = getttyent()) != NULL) { - ++session_index; - - for (sprev = 0, sp = sessions; sp; sprev = sp, sp = sp->se_next) - if (strcmp(typ->ty_name, sp->se_device + devlen) == 0) - break; - - if (sp) { - sp->se_flags |= SE_PRESENT; - if (sp->se_index != session_index) { - warning("port `%s' changed utmp index from " - "%d to %d", sp->se_device, sp->se_index, - session_index); - sp->se_index = session_index; - } - if ((typ->ty_status & TTY_ON) == 0 || - typ->ty_getty == 0) { - sp->se_flags |= SE_SHUTDOWN; - if (sp->se_process != 0) - (void)kill(sp->se_process, SIGHUP); - continue; - } - sp->se_flags &= ~SE_SHUTDOWN; - if (setupargv(sp, typ) == 0) { - warning("can't parse getty for port `%s'", - sp->se_device); - sp->se_flags |= SE_SHUTDOWN; - if (sp->se_process != 0) - (void)kill(sp->se_process, SIGHUP); - } - continue; - } - - (void)new_session(sprev, session_index, typ); - } - - (void)endttyent(); - - for (sp = sessions; sp; sp = sp->se_next) - if ((sp->se_flags & SE_PRESENT) == 0) { - sp->se_flags |= SE_SHUTDOWN; - if (sp->se_process != 0) - (void)kill(sp->se_process, SIGHUP); - } - - return (state_func_t)multi_user; -} - -/* - * Block further logins. - */ -static state_func_t -catatonia(void) -{ - session_t *sp; - - for (sp = sessions; sp; sp = sp->se_next) - sp->se_flags |= SE_SHUTDOWN; - - return (state_func_t)multi_user; -} -#endif /* LETS_GET_SMALL */ - -/* - * Note SIGALRM. - */ -static void -/*ARGSUSED*/ -alrm_handler(int sig) -{ - - clang = 1; -} - -#ifndef LETS_GET_SMALL -/* - * Bring the system down to single user. - */ -static state_func_t -death(void) -{ - session_t *sp; - int i, status; - pid_t pid; - static const int death_sigs[3] = { SIGHUP, SIGTERM, SIGKILL }; - - for (sp = sessions; sp; sp = sp->se_next) - sp->se_flags |= SE_SHUTDOWN; - - /* NB: should send a message to the session logger to avoid blocking. */ -#ifdef SUPPORT_UTMPX - logwtmpx("~", "shutdown", "", 0, INIT_PROCESS); -#endif -#ifdef SUPPORT_UTMP - logwtmp("~", "shutdown", ""); -#endif - - for (i = 0; i < 3; ++i) { - if (kill(-1, death_sigs[i]) == -1 && errno == ESRCH) - return (state_func_t)single_user; - - clang = 0; - (void)alarm(DEATH_WATCH); - do - if ((pid = waitpid(-1, &status, 0)) != -1) - collect_child(pid, status); - while (clang == 0 && errno != ECHILD); - - if (errno == ECHILD) - return (state_func_t)single_user; - } - - warning("some processes would not die; ps axl advised"); - - return (state_func_t)single_user; -} -#endif /* LETS_GET_SMALL */ - -#ifdef MFS_DEV_IF_NO_CONSOLE - -static int -mfs_dev(void) -{ - /* - * We cannot print errors so we bail out silently... - */ - pid_t pid; - int status; - - /* If we have /dev/console, assume all is OK */ - if (access(_PATH_CONSOLE, F_OK) == 0) - return 0; - -#if 0 /* Useful for testing MAKEDEV */ - /* Mount an mfs over /mnt so we can create a console entry */ - switch ((pid = fork())) { - case 0: - (void)execl(INIT_MOUNT_MFS, "mount_mfs", - "-b", "4096", "-f", "512", - "-s", 64, "-n", 10, - "-p", "0755", - "swap", "/mnt", NULL); - _exit(9); - /*NOTREACHED*/ - - case -1: - return(-1); - - default: - if (waitpid(pid, &status, 0) == -1) - return(-1); - if (status != 0) - return(-1); - break; - } - - { - dev_t dev; -#ifdef CPU_CONSDEV - static int name[2] = { CTL_MACHDEP, CPU_CONSDEV }; - size_t olen; - olen = sizeof(dev); - if (sysctl(name, sizeof(name) / sizeof(name[0]), &dev, &olen, - NULL, 0) == -1) -#endif - dev = makedev(0, 0); - - /* Make a console for us, so we can see things happening */ - if (mknod("/mnt/console", 0666 | S_IFCHR, dev) == -1) - return(-1); - (void)freopen("/mnt/console", "a", stderr); - } - -#endif - - /* Run the makedev script to create devices */ - switch ((pid = fork())) { - case 0: - (void)dup2(2, 1); /* Give the script stdout */ - if (chdir("/dev") == 0) - (void)execl(INIT_BSHELL, "sh", - access("./MAKEDEV", X_OK) == 0 - ? "./MAKEDEV" : "/etc/MAKEDEV", - "-MM", "init", NULL); - _exit(10); - /* NOTREACHED */ - - case -1: - break; - - default: - if (waitpid(pid, &status, 0) == -1) - break; - if (status != 0) - warn("MAKEDEV exit status %d", status); - /* - * If /dev/console got created, then return 0 - * regardless of MAKEDEV exit status. - */ - if (access(_PATH_CONSOLE, F_OK) == 0) - return 0; - _exit(11); - } - warn("Unable to run MAKEDEV"); - _exit(12); -} -#endif - -#ifndef LETS_GET_SMALL -static int -do_setttyent(void) -{ - (void)endttyent(); -#ifdef CHROOT - if (did_multiuser_chroot) { - char path[PATH_MAX]; - - (void)snprintf(path, sizeof(path), "%s/%s", rootdir, _PATH_TTYS); - - return setttyentpath(path); - } else -#endif /* CHROOT */ - return setttyent(); -} -#endif - -#if !defined(LETS_GET_SMALL) && defined(CHROOT) - -static int -createsysctlnode(void) -{ - struct sysctlnode node; - int mib[2]; - size_t len; - - /* - * Create top-level dynamic sysctl node. Its child nodes will only - * be readable by the superuser, since regular mortals should not - * care ("Sssh, it's a secret!"). - */ - len = sizeof(struct sysctlnode); - mib[0] = CTL_CREATE; - - (void)memset(&node, 0, len); - node.sysctl_flags = SYSCTL_VERSION | CTLFLAG_READWRITE | - CTLFLAG_PRIVATE | CTLTYPE_NODE; - node.sysctl_num = CTL_CREATE; - (void)snprintf(node.sysctl_name, SYSCTL_NAMELEN, "init"); - if (sysctl(&mib[0], 1, &node, &len, &node, len) == -1) { - warning("could not create init node: %m"); - return -1; - } - - /* - * Create second level dynamic node capable of holding pathname. - * Provide "/" as the default value. - */ - len = sizeof(struct sysctlnode); - mib[0] = node.sysctl_num; - mib[1] = CTL_CREATE; - - (void)memset(&node, 0, len); - node.sysctl_flags = SYSCTL_VERSION | CTLFLAG_READWRITE | - CTLTYPE_STRING | CTLFLAG_OWNDATA; - node.sysctl_size = _POSIX_PATH_MAX; - node.sysctl_data = __UNCONST("/"); - node.sysctl_num = CTL_CREATE; - (void)snprintf(node.sysctl_name, SYSCTL_NAMELEN, "root"); - if (sysctl(&mib[0], 2, NULL, NULL, &node, len) == -1) { - warning("could not create init.root node: %m"); - return -1; - } - - return 0; -} - -static int -shouldchroot(void) -{ - struct sysctlnode node; - size_t len, cnt; - int mib; - - len = sizeof(struct sysctlnode); - - if (sysctlbyname("init.root", rootdir, &len, NULL, 0) == -1) { - warning("could not read init.root: %m"); - - /* Child killed our node. Recreate it. */ - if (errno == ENOENT) { - /* Destroy whatever is left, recreate from scratch. */ - if (sysctlnametomib("init", &mib, &cnt) != -1) { - (void)memset(&node, 0, sizeof(node)); - node.sysctl_flags = SYSCTL_VERSION; - node.sysctl_num = mib; - mib = CTL_DESTROY; - - (void)sysctl(&mib, 1, NULL, NULL, &node, - sizeof(node)); - } - - (void)createsysctlnode(); - } - - /* We certainly won't chroot. */ - return 0; - } - - if (rootdir[len] != '\0' || strlen(rootdir) != len - 1) { - warning("init.root is not a string"); - return 0; - } - - if (strcmp(rootdir, "/") == 0) - return 0; - - return 1; -} - -#endif /* !LETS_GET_SMALL && CHROOT */ diff --git a/sbin/init/pathnames.h b/sbin/init/pathnames.h deleted file mode 100644 index 222e35084..000000000 --- a/sbin/init/pathnames.h +++ /dev/null @@ -1,40 +0,0 @@ -/* $NetBSD: pathnames.h,v 1.6 2003/08/07 10:04:25 agc Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Donn Seeley at Berkeley Software Design, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)pathnames.h 8.1 (Berkeley) 6/5/93 - */ - -#include - -#define _PATH_SLOGGER "/sbin/session_logger" -#define _PATH_RUNCOM "/etc/rc" diff --git a/sbin/mount/fattr.c b/sbin/mount/fattr.c deleted file mode 100644 index aabb5605e..000000000 --- a/sbin/mount/fattr.c +++ /dev/null @@ -1,89 +0,0 @@ -/* $NetBSD: fattr.c,v 1.10 2009/06/19 12:55:45 stacktic Exp $ */ - -/*- - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifndef lint -__RCSID("$NetBSD: fattr.c,v 1.10 2009/06/19 12:55:45 stacktic Exp $"); -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mountprog.h" - -int -a_num(const char *s, const char *id_type) -{ - int id; - char *ep; - - id = strtol(s, &ep, 0); - if (*ep || s == ep || id < 0) - errx(1, "unknown %s id: %s", id_type, s); - return id; -} - -gid_t -a_gid(const char *s) -{ - struct group *gr; - - if ((gr = getgrnam(s)) != NULL) - return gr->gr_gid; - return a_num(s, "group"); -} - -uid_t -a_uid(const char *s) -{ - struct passwd *pw; - - if ((pw = getpwnam(s)) != NULL) - return pw->pw_uid; - return a_num(s, "user"); -} - -mode_t -a_mask(const char *s) -{ - int rv; - char *ep; - - rv = strtol(s, &ep, 8); - if (s == ep || *ep || rv < 0) - errx(1, "invalid file mode: %s", s); - return rv; -} diff --git a/sbin/mount/mountprog.h b/sbin/mount/mountprog.h deleted file mode 100644 index 2c7327430..000000000 --- a/sbin/mount/mountprog.h +++ /dev/null @@ -1,37 +0,0 @@ -/* $NetBSD: mountprog.h,v 1.1 2008/08/05 20:57:45 pooka Exp $ */ - -/*- - * Copyright (c) 2000, 2008 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -int a_num(const char *, const char *); -gid_t a_gid(const char *); -uid_t a_uid(const char *); -mode_t a_mask(const char *); - -int checkvfsname(const char *, const char **); -const char ** makevfslist(const char *); - -void pathadj(const char *, char *); diff --git a/sbin/newfs_ext2fs/Makefile b/sbin/newfs_ext2fs/Makefile deleted file mode 100644 index 40a44b9a0..000000000 --- a/sbin/newfs_ext2fs/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# $NetBSD: Makefile,v 1.6 2013/11/09 21:39:27 christos Exp $ -# @(#)Makefile 8.2 (Berkeley) 3/27/94 - -CWARNFLAGS+= -Wno-sign-compare - -.include - -PROG= newfs_ext2fs -SRCS= newfs_ext2fs.c mke2fs.c ext2fs_bswap.c partutil.c -MAN= newfs_ext2fs.8 - -FSCK=${NETBSDSRCDIR}/sbin/fsck -CPPFLAGS+=-I${.CURDIR} -I${FSCK} - -DPADD+= ${LIBUTIL} -LDADD+= -lutil - -LDADD+=-lprop -DPADD+=${LIBPROP} - -.PATH: ${NETBSDSRCDIR}/sys/ufs/ext2fs ${FSCK} - -.if ${MACHINE_ARCH} == "vax" -COPTS.mke2fs.c=-O0 -.endif - -.include diff --git a/sbin/newfs_ext2fs/extern.h b/sbin/newfs_ext2fs/extern.h deleted file mode 100644 index 809bd6f9d..000000000 --- a/sbin/newfs_ext2fs/extern.h +++ /dev/null @@ -1,45 +0,0 @@ -/* $NetBSD: extern.h,v 1.4 2009/10/21 01:07:46 snj Exp $ */ - -/* - * Copyright (c) 1997 Christos Zoulas. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* XXX should be in */ -#define EXT2_LOG_MAXBSIZE 12 -#define EXT2_MAXBSIZE (1 << EXT2_LOG_MAXBSIZE) - -/* prototypes */ -void mke2fs(const char *, int, int); - -/* variables set up by front end. */ -extern int Nflag; /* run mkfs without writing file system */ -extern int Oflag; /* format as an 4.3BSD file system */ -extern int verbosity; /* amount of printf() output */ -extern int64_t fssize; /* file system size */ -extern uint16_t inodesize; /* bytes per inode */ -extern uint sectorsize; /* sector size */ -extern uint fsize; /* fragment size */ -extern uint bsize; /* block size */ -extern uint minfree; /* free space threshold */ -extern uint num_inodes; /* number of inodes (overrides density) */ -extern char *volname; /* volume name */ diff --git a/sbin/newfs_ext2fs/mke2fs.c b/sbin/newfs_ext2fs/mke2fs.c deleted file mode 100644 index c43e415ae..000000000 --- a/sbin/newfs_ext2fs/mke2fs.c +++ /dev/null @@ -1,1444 +0,0 @@ -/* $NetBSD: mke2fs.c,v 1.22 2015/06/16 23:18:55 christos Exp $ */ - -/*- - * Copyright (c) 2007 Izumi Tsutsui. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Copyright (c) 1980, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1997 Manuel Bouyer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * mke2fs.c: "re-invent (dumb but non-GPLed) wheel as a fun project" - * - * In spite of this name, there is no piece of code - * derived from GPLed e2fsprogs written for Linux. - * I referred them only to see how each structure - * member should be initialized. - * - * Reference: - * - All NetBSD sources under src/sys/ufs/ext2fs and src/sbin/fsck_ext2fs - * - Ext2fs Home Page - * http://e2fsprogs.sourceforge.net/ext2.html - * - Design and Implementation of the Second Extended Filesystem - * http://e2fsprogs.sourceforge.net/ext2intro.html - * - Linux Documentation "The Second Extended Filesystem" - * http://www.kernel.org/doc/Documentation/filesystems/ext2.txt - */ - -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)mkfs.c 8.11 (Berkeley) 5/3/95"; -#else -__RCSID("$NetBSD: mke2fs.c,v 1.22 2015/06/16 23:18:55 christos Exp $"); -#endif -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "extern.h" - -static void initcg(uint); -static void zap_old_sblock(int); -static uint cgoverhead(uint); -static int fsinit(const struct timeval *); -static int makedir(struct ext2fs_direct *, int); -static void copy_dir(struct ext2fs_direct *, struct ext2fs_direct *); -static void init_resizeino(const struct timeval *); -static uint32_t alloc(uint32_t, uint16_t); -static void iput(struct ext2fs_dinode *, ino_t); -static void rdfs(daddr_t, int, void *); -static void wtfs(daddr_t, int, void *); -static int ilog2(uint); -static int skpc(int, size_t, uint8_t *); - -/* XXX: some of these macro should be into ? */ -#define EXT2_DEF_MAX_MNT_COUNT 20 -#define EXT2_DEF_FSCKINTV (180 * 24 * 60 * 60) /* 180 days */ -#define EXT2_RESERVED_INODES (EXT2_FIRSTINO - 1) -#define EXT2_UMASK 0755 - -#define EXT2_INO_INDEX(ino) ((ino) - 1) /* no inode zero */ - -#define EXT2_LOSTFOUNDSIZE 16384 -#define EXT2_LOSTFOUNDINO EXT2_FIRSTINO /* XXX: not quite */ -#define EXT2_LOSTFOUNDUMASK 0700 - -#define EXT2_RESIZEINOUMASK 0600 - -#define NBLOCK_SUPERBLOCK 1 -#define NBLOCK_BLOCK_BITMAP 1 -#define NBLOCK_INODE_BITMAP 1 - -#define cgbase(fs, c) \ - ((fs)->e2fs.e2fs_first_dblock + (fs)->e2fs.e2fs_bpg * (c)) - - -/* - * ext2fs super block and group descriptor structures - * - * We don't have to use or setup whole in-memory m_ext2fs structure, - * but prepare it to use several macro defined in kernel headers. - */ -union { - struct m_ext2fs m_ext2fs; - char pad[SBSIZE]; -} ext2fsun; -#define sblock ext2fsun.m_ext2fs -#define gd ext2fsun.m_ext2fs.e2fs_gd - -static uint8_t *iobuf; /* for superblock and group descriptors */ -static int iobufsize; - -static uint8_t buf[MAXBSIZE]; /* for initcg() and makedir() ops */ - -static int fsi, fso; - -void -mke2fs(const char *fsys, int fi, int fo) -{ - struct timeval tv; - int64_t minfssize; - uint bcount, fbcount, ficount; - uint blocks_gd, blocks_per_cg, inodes_per_cg, iblocks_per_cg; - uint minblocks_per_cg, blocks_lastcg; - uint ncg, cylno, sboff; - uuid_t uuid; - uint32_t uustat; - int i, len, col, delta, fld_width, max_cols; - struct winsize winsize; - - gettimeofday(&tv, NULL); - fsi = fi; - fso = fo; - - /* - * collect and verify the block and fragment sizes - */ - if (!powerof2(bsize)) { - errx(EXIT_FAILURE, - "block size must be a power of 2, not %u", - bsize); - } - if (!powerof2(fsize)) { - errx(EXIT_FAILURE, - "fragment size must be a power of 2, not %u", - fsize); - } - if (fsize < sectorsize) { - errx(EXIT_FAILURE, - "fragment size %u is too small, minimum is %u", - fsize, sectorsize); - } - if (bsize < MINBSIZE) { - errx(EXIT_FAILURE, - "block size %u is too small, minimum is %u", - bsize, MINBSIZE); - } - if (bsize > EXT2_MAXBSIZE) { - errx(EXIT_FAILURE, - "block size %u is too large, maximum is %u", - bsize, MAXBSIZE); - } - if (bsize != fsize) { - /* - * There is no fragment support on current ext2fs (yet?), - * but some kernel code refers fsize or fpg as bsize or bpg - * and Linux seems to set the same values to them. - */ - errx(EXIT_FAILURE, - "block size (%u) can't be different from " - "fragment size (%u)", - bsize, fsize); - } - - /* variable inodesize is REV1 feature */ - if (Oflag == 0 && inodesize != EXT2_REV0_DINODE_SIZE) { - errx(EXIT_FAILURE, "GOOD_OLD_REV file system format" - " doesn't support %d byte inode", inodesize); - } - - sblock.e2fs.e2fs_log_bsize = ilog2(bsize) - LOG_MINBSIZE; - /* Umm, why not e2fs_log_fsize? */ - sblock.e2fs.e2fs_fsize = ilog2(fsize) - LOG_MINBSIZE; - - sblock.e2fs_bsize = bsize; - sblock.e2fs_bshift = sblock.e2fs.e2fs_log_bsize + LOG_MINBSIZE; - sblock.e2fs_qbmask = sblock.e2fs_bsize - 1; - sblock.e2fs_bmask = ~sblock.e2fs_qbmask; - sblock.e2fs_fsbtodb = ilog2(sblock.e2fs_bsize) - ilog2(sectorsize); - sblock.e2fs_ipb = sblock.e2fs_bsize / inodesize; - - /* - * Ext2fs preserves BBSIZE (1024 bytes) space at the top for - * bootloader (though it is not enough at all for our bootloader). - * If bsize == BBSIZE we have to preserve one block. - * If bsize > BBSIZE, the first block already contains BBSIZE space - * before superblock because superblock is allocated at SBOFF and - * bsize is a power of two (i.e. 2048 bytes or more). - */ - sblock.e2fs.e2fs_first_dblock = (sblock.e2fs_bsize > BBSIZE) ? 0 : 1; - minfssize = EXT2_FSBTODB(&sblock, - sblock.e2fs.e2fs_first_dblock + - NBLOCK_SUPERBLOCK + - 1 /* at least one group descriptor */ + - NBLOCK_BLOCK_BITMAP + - NBLOCK_INODE_BITMAP + - 1 /* at least one inode table block */ + - 1 /* at least one data block for rootdir */ + - 1 /* at least one data block for data */ - ); /* XXX and more? */ - - if (fssize < minfssize) - errx(EXIT_FAILURE, "Filesystem size %" PRId64 - " < minimum size of %" PRId64, fssize, minfssize); - - bcount = EXT2_DBTOFSB(&sblock, fssize); - - /* - * While many people claim that ext2fs is a (bad) clone of ufs/ffs, - * it isn't actual ffs so maybe we should call it "block group" - * as their native name rather than ffs derived "cylinder group." - * But we'll use the latter here since other kernel sources use it. - * (I also agree "cylinder" based allocation is obsolete though) - */ - - /* maybe "simple is the best" */ - blocks_per_cg = sblock.e2fs_bsize * NBBY; - - ncg = howmany(bcount - sblock.e2fs.e2fs_first_dblock, blocks_per_cg); - blocks_gd = howmany(sizeof(struct ext2_gd) * ncg, bsize); - - /* check range of inode number */ - if (num_inodes < EXT2_FIRSTINO) - num_inodes = EXT2_FIRSTINO; /* needs reserved inodes + 1 */ - if (num_inodes > UINT16_MAX * ncg) - num_inodes = UINT16_MAX * ncg; /* ext2bgd_nifree is uint16_t */ - - inodes_per_cg = num_inodes / ncg; - iblocks_per_cg = howmany(inodesize * inodes_per_cg, bsize); - - /* Check that the last cylinder group has enough space for inodes */ - minblocks_per_cg = - NBLOCK_BLOCK_BITMAP + - NBLOCK_INODE_BITMAP + - iblocks_per_cg + - 1; /* at least one data block */ - if (Oflag == 0 || cg_has_sb(ncg - 1) != 0) - minblocks_per_cg += NBLOCK_SUPERBLOCK + blocks_gd; - - blocks_lastcg = bcount - sblock.e2fs.e2fs_first_dblock - - blocks_per_cg * (ncg - 1); - if (blocks_lastcg < minblocks_per_cg) { - /* - * Since we make all the cylinder groups the same size, the - * last will only be small if there are more than one - * cylinder groups. If the last one is too small to store - * filesystem data, just kill it. - * - * XXX: Does fsck_ext2fs(8) properly handle this case? - */ - bcount -= blocks_lastcg; - ncg--; - blocks_lastcg = blocks_per_cg; - blocks_gd = howmany(sizeof(struct ext2_gd) * ncg, bsize); - inodes_per_cg = num_inodes / ncg; - } - /* roundup inodes_per_cg to make it use whole inode table blocks */ - inodes_per_cg = roundup(inodes_per_cg, sblock.e2fs_ipb); - num_inodes = inodes_per_cg * ncg; - iblocks_per_cg = inodes_per_cg / sblock.e2fs_ipb; - - /* XXX: probably we should check these adjusted values again */ - - sblock.e2fs.e2fs_bcount = bcount; - sblock.e2fs.e2fs_icount = num_inodes; - - sblock.e2fs_ncg = ncg; - sblock.e2fs_ngdb = blocks_gd; - sblock.e2fs_itpg = iblocks_per_cg; - - sblock.e2fs.e2fs_rbcount = sblock.e2fs.e2fs_bcount * minfree / 100; - /* e2fs_fbcount will be accounted later */ - /* e2fs_ficount will be accounted later */ - - sblock.e2fs.e2fs_bpg = blocks_per_cg; - sblock.e2fs.e2fs_fpg = blocks_per_cg; - - sblock.e2fs.e2fs_ipg = inodes_per_cg; - - sblock.e2fs.e2fs_mtime = 0; - sblock.e2fs.e2fs_wtime = tv.tv_sec; - sblock.e2fs.e2fs_mnt_count = 0; - /* XXX: should add some entropy to avoid checking all fs at once? */ - sblock.e2fs.e2fs_max_mnt_count = EXT2_DEF_MAX_MNT_COUNT; - - sblock.e2fs.e2fs_magic = E2FS_MAGIC; - sblock.e2fs.e2fs_state = E2FS_ISCLEAN; - sblock.e2fs.e2fs_beh = E2FS_BEH_DEFAULT; - sblock.e2fs.e2fs_minrev = 0; - sblock.e2fs.e2fs_lastfsck = tv.tv_sec; - sblock.e2fs.e2fs_fsckintv = EXT2_DEF_FSCKINTV; - - /* - * Maybe we can use E2FS_OS_FREEBSD here and it would be more proper, - * but the purpose of this newfs_ext2fs(8) command is to provide - * a filesystem which can be recognized by firmware on some - * Linux based appliances that can load bootstrap files only from - * (their native) ext2fs, and anyway we will (and should) try to - * act like them as much as possible. - * - * Anyway, I hope that all newer such boxes will keep their support - * for the "GOOD_OLD_REV" ext2fs. - */ - sblock.e2fs.e2fs_creator = E2FS_OS_LINUX; - - if (Oflag == 0) { - sblock.e2fs.e2fs_rev = E2FS_REV0; - sblock.e2fs.e2fs_features_compat = 0; - sblock.e2fs.e2fs_features_incompat = 0; - sblock.e2fs.e2fs_features_rocompat = 0; - } else { - sblock.e2fs.e2fs_rev = E2FS_REV1; - /* - * e2fsprogs say "REV1" is "dynamic" so - * it isn't quite a version and maybe it means - * "extended from REV0 so check compat features." - * - * XXX: We don't have any native tool to activate - * the EXT2F_COMPAT_RESIZE feature and - * fsck_ext2fs(8) might not fix structures for it. - */ - sblock.e2fs.e2fs_features_compat = EXT2F_COMPAT_RESIZE; - sblock.e2fs.e2fs_features_incompat = EXT2F_INCOMPAT_FTYPE; - sblock.e2fs.e2fs_features_rocompat = - EXT2F_ROCOMPAT_SPARSESUPER | EXT2F_ROCOMPAT_LARGEFILE; - } - - sblock.e2fs.e2fs_ruid = geteuid(); - sblock.e2fs.e2fs_rgid = getegid(); - - sblock.e2fs.e2fs_first_ino = EXT2_FIRSTINO; - sblock.e2fs.e2fs_inode_size = inodesize; - - /* e2fs_block_group_nr is set on writing superblock to each group */ - - uuid_create(&uuid, &uustat); - if (uustat != uuid_s_ok) - errx(EXIT_FAILURE, "Failed to generate uuid"); - uuid_enc_le(sblock.e2fs.e2fs_uuid, &uuid); - if (volname != NULL) { - if (strlen(volname) > sizeof(sblock.e2fs.e2fs_vname)) - errx(EXIT_FAILURE, "Volume name is too long"); - strlcpy(sblock.e2fs.e2fs_vname, volname, - sizeof(sblock.e2fs.e2fs_vname)); - } - - sblock.e2fs.e2fs_fsmnt[0] = '\0'; - sblock.e2fs_fsmnt[0] = '\0'; - - sblock.e2fs.e2fs_algo = 0; /* XXX unsupported? */ - sblock.e2fs.e2fs_prealloc = 0; /* XXX unsupported? */ - sblock.e2fs.e2fs_dir_prealloc = 0; /* XXX unsupported? */ - - /* calculate blocks for reserved group descriptors for resize */ - sblock.e2fs.e2fs_reserved_ngdb = 0; - if (sblock.e2fs.e2fs_rev > E2FS_REV0 && - (sblock.e2fs.e2fs_features_compat & EXT2F_COMPAT_RESIZE) != 0) { - uint64_t target_blocks; - uint target_ncg, target_ngdb, reserved_ngdb; - - /* reserve descriptors for size as 1024 times as current */ - target_blocks = - (sblock.e2fs.e2fs_bcount - sblock.e2fs.e2fs_first_dblock) - * 1024ULL; - /* number of blocks must be in uint32_t */ - if (target_blocks > UINT32_MAX) - target_blocks = UINT32_MAX; - target_ncg = howmany(target_blocks, sblock.e2fs.e2fs_bpg); - target_ngdb = howmany(sizeof(struct ext2_gd) * target_ncg, - sblock.e2fs_bsize); - /* - * Reserved group descriptor blocks are preserved as - * the second level double indirect reference blocks in - * the EXT2_RESIZEINO inode, so the maximum number of - * the blocks is EXT2_NINDIR(fs). - * (see also descriptions in init_resizeino() function) - * - * We check a number including current e2fs_ngdb here - * because they will be moved into reserved gdb on - * possible future size shrink, though e2fsprogs don't - * seem to care about it. - */ - if (target_ngdb > EXT2_NINDIR(&sblock)) - target_ngdb = EXT2_NINDIR(&sblock); - - reserved_ngdb = target_ngdb - sblock.e2fs_ngdb; - - /* make sure reserved_ngdb fits in the last cg */ - if (reserved_ngdb >= blocks_lastcg - cgoverhead(ncg - 1)) - reserved_ngdb = blocks_lastcg - cgoverhead(ncg - 1); - if (reserved_ngdb == 0) { - /* if no space for reserved gdb, disable the feature */ - sblock.e2fs.e2fs_features_compat &= - ~EXT2F_COMPAT_RESIZE; - } - sblock.e2fs.e2fs_reserved_ngdb = reserved_ngdb; - } - - /* - * Initialize group descriptors - */ - gd = malloc(sblock.e2fs_ngdb * bsize); - if (gd == NULL) - errx(EXIT_FAILURE, "Can't allocate descriptors buffer"); - memset(gd, 0, sblock.e2fs_ngdb * bsize); - - fbcount = 0; - ficount = 0; - for (cylno = 0; cylno < ncg; cylno++) { - uint boffset; - - boffset = cgbase(&sblock, cylno); - if (sblock.e2fs.e2fs_rev == E2FS_REV0 || - (sblock.e2fs.e2fs_features_rocompat & - EXT2F_ROCOMPAT_SPARSESUPER) == 0 || - cg_has_sb(cylno)) { - boffset += NBLOCK_SUPERBLOCK + sblock.e2fs_ngdb; - if (sblock.e2fs.e2fs_rev > E2FS_REV0 && - (sblock.e2fs.e2fs_features_compat & - EXT2F_COMPAT_RESIZE) != 0) - boffset += sblock.e2fs.e2fs_reserved_ngdb; - } - gd[cylno].ext2bgd_b_bitmap = boffset; - boffset += NBLOCK_BLOCK_BITMAP; - gd[cylno].ext2bgd_i_bitmap = boffset; - boffset += NBLOCK_INODE_BITMAP; - gd[cylno].ext2bgd_i_tables = boffset; - if (cylno == (ncg - 1)) - gd[cylno].ext2bgd_nbfree = - blocks_lastcg - cgoverhead(cylno); - else - gd[cylno].ext2bgd_nbfree = - sblock.e2fs.e2fs_bpg - cgoverhead(cylno); - fbcount += gd[cylno].ext2bgd_nbfree; - gd[cylno].ext2bgd_nifree = sblock.e2fs.e2fs_ipg; - if (cylno == 0) { - /* take reserved inodes off nifree */ - gd[cylno].ext2bgd_nifree -= EXT2_RESERVED_INODES; - } - ficount += gd[cylno].ext2bgd_nifree; - gd[cylno].ext2bgd_ndirs = 0; - } - sblock.e2fs.e2fs_fbcount = fbcount; - sblock.e2fs.e2fs_ficount = ficount; - - /* - * Dump out summary information about file system. - */ - if (verbosity > 0) { - printf("%s: %u.%1uMB (%" PRId64 " sectors) " - "block size %u, fragment size %u\n", - fsys, - (uint)(((uint64_t)bcount * bsize) / (1024 * 1024)), - (uint)((uint64_t)bcount * bsize - - rounddown((uint64_t)bcount * bsize, 1024 * 1024)) - / 1024 / 100, - fssize, bsize, fsize); - printf("\tusing %u block groups of %u.0MB, %u blks, " - "%u inodes.\n", - ncg, bsize * sblock.e2fs.e2fs_bpg / (1024 * 1024), - sblock.e2fs.e2fs_bpg, sblock.e2fs.e2fs_ipg); - } - - /* - * allocate space for superblock and group descriptors - */ - iobufsize = (NBLOCK_SUPERBLOCK + sblock.e2fs_ngdb) * sblock.e2fs_bsize; - iobuf = mmap(0, iobufsize, PROT_READ|PROT_WRITE, - MAP_ANON|MAP_PRIVATE, -1, 0); - if (iobuf == NULL) - errx(EXIT_FAILURE, "Cannot allocate I/O buffer"); - memset(iobuf, 0, iobufsize); - - /* - * We now start writing to the filesystem - */ - - if (!Nflag) { - static const uint pbsize[] = { 1024, 2048, 4096, 0 }; - uint pblock; - /* - * Validate the given file system size. - * Verify that its last block can actually be accessed. - * Convert to file system fragment sized units. - */ - if (fssize <= 0) - errx(EXIT_FAILURE, "Preposterous size %" PRId64, - fssize); - wtfs(fssize - 1, sectorsize, iobuf); - - /* - * Ensure there is nothing that looks like a filesystem - * superblock anywhere other than where ours will be. - * - * Ext2fs superblock is always placed at the same SBOFF, - * so we just zap possible first backups. - */ - for (i = 0; pbsize[i] != 0; i++) { - pblock = (pbsize[i] > BBSIZE) ? 0 : 1; /* 1st dblk */ - pblock += pbsize[i] * NBBY; /* next bg */ - /* zap first backup */ - zap_old_sblock(pblock * pbsize[i]); - } - /* - * Also zap possbile FFS magic leftover to prevent - * kernel vfs_mountroot() and bootloadres from mis-recognizing - * this file system as FFS. - */ - zap_old_sblock(8192); /* SBLOCK_UFS1 */ - zap_old_sblock(65536); /* SBLOCK_UFS2 */ - } - - if (verbosity >= 3) - printf("super-block backups (for fsck_ext2fs -b #) at:\n"); - /* If we are printing more than one line of numbers, line up columns */ - fld_width = verbosity < 4 ? 1 : snprintf(NULL, 0, "%" PRIu64, - (uint64_t)cgbase(&sblock, ncg - 1)); - /* Get terminal width */ - if (ioctl(fileno(stdout), TIOCGWINSZ, &winsize) == 0) - max_cols = winsize.ws_col; - else - max_cols = 80; - if (Nflag && verbosity == 3) - /* Leave space to add " ..." after one row of numbers */ - max_cols -= 4; -#define BASE 0x10000 /* For some fixed-point maths */ - col = 0; - delta = verbosity > 2 ? 0 : max_cols * BASE / ncg; - for (cylno = 0; cylno < ncg; cylno++) { - fflush(stdout); - initcg(cylno); - if (verbosity < 2) - continue; - /* the first one is a master, not backup */ - if (cylno == 0) - continue; - /* skip if this cylinder doesn't have a backup */ - if (sblock.e2fs.e2fs_rev > E2FS_REV0 && - (sblock.e2fs.e2fs_features_rocompat & - EXT2F_ROCOMPAT_SPARSESUPER) != 0 && - cg_has_sb(cylno) == 0) - continue; - - if (delta > 0) { - if (Nflag) - /* No point doing dots for -N */ - break; - /* Print dots scaled to end near RH margin */ - for (col += delta; col > BASE; col -= BASE) - printf("."); - continue; - } - /* Print superblock numbers */ - len = printf("%s%*" PRIu64 ",", (col ? " " : ""), fld_width, - (uint64_t)cgbase(&sblock, cylno)); - col += len; - if (col + len < max_cols) - /* Next number fits */ - continue; - /* Next number won't fit, need a newline */ - if (verbosity <= 3) { - /* Print dots for subsequent cylinder groups */ - delta = sblock.e2fs_ncg - cylno - 1; - if (delta != 0) { - if (Nflag) { - printf(" ..."); - break; - } - delta = max_cols * BASE / delta; - } - } - col = 0; - printf("\n"); - } -#undef BASE - if (col > 0) - printf("\n"); - if (Nflag) - return; - - /* - * Now construct the initial file system, - */ - if (fsinit(&tv) == 0) - errx(EXIT_FAILURE, "Error making filesystem"); - /* - * Write out the superblock and group descriptors - */ - sblock.e2fs.e2fs_block_group_nr = 0; - sboff = 0; - if (cgbase(&sblock, 0) == 0) { - /* - * If the first block contains the boot block sectors, - * (i.e. in case of sblock.e2fs.e2fs_bsize > BBSIZE) - * we have to preserve data in it. - */ - sboff = SBOFF; - } - e2fs_sbsave(&sblock.e2fs, (struct ext2fs *)(iobuf + sboff)); - e2fs_cgsave(gd, (struct ext2_gd *)(iobuf + sblock.e2fs_bsize), - sizeof(struct ext2_gd) * sblock.e2fs_ncg); - wtfs(EXT2_FSBTODB(&sblock, cgbase(&sblock, 0)) + sboff / sectorsize, - iobufsize - sboff, iobuf + sboff); - - munmap(iobuf, iobufsize); -} - -/* - * Initialize a cylinder (block) group. - */ -void -initcg(uint cylno) -{ - uint nblcg, i, j, sboff; - struct ext2fs_dinode *dp; - - /* - * Make a copy of the superblock and group descriptors. - */ - if (sblock.e2fs.e2fs_rev == E2FS_REV0 || - (sblock.e2fs.e2fs_features_rocompat & - EXT2F_ROCOMPAT_SPARSESUPER) == 0 || - cg_has_sb(cylno)) { - sblock.e2fs.e2fs_block_group_nr = cylno; - sboff = 0; - if (cgbase(&sblock, cylno) == 0) { - /* preserve data in bootblock in cg0 */ - sboff = SBOFF; - } - e2fs_sbsave(&sblock.e2fs, (struct ext2fs *)(iobuf + sboff)); - e2fs_cgsave(gd, (struct ext2_gd *)(iobuf + - sblock.e2fs_bsize * NBLOCK_SUPERBLOCK), - sizeof(struct ext2_gd) * sblock.e2fs_ncg); - /* write superblock and group descriptor backups */ - wtfs(EXT2_FSBTODB(&sblock, cgbase(&sblock, cylno)) + - sboff / sectorsize, iobufsize - sboff, iobuf + sboff); - } - - /* - * Initialize block bitmap. - */ - memset(buf, 0, sblock.e2fs_bsize); - if (cylno == (sblock.e2fs_ncg - 1)) { - /* The last group could have less blocks than e2fs_bpg. */ - nblcg = sblock.e2fs.e2fs_bcount - - cgbase(&sblock, sblock.e2fs_ncg - 1); - for (i = nblcg; i < roundup(nblcg, NBBY); i++) - setbit(buf, i); - memset(&buf[i / NBBY], ~0U, sblock.e2fs.e2fs_bpg - i); - } - /* set overhead (superblock, group descriptor etc.) blocks used */ - for (i = 0; i < cgoverhead(cylno) / NBBY; i++) - buf[i] = ~0; - i = i * NBBY; - for (; i < cgoverhead(cylno); i++) - setbit(buf, i); - wtfs(EXT2_FSBTODB(&sblock, gd[cylno].ext2bgd_b_bitmap), - sblock.e2fs_bsize, buf); - - /* - * Initialize inode bitmap. - * - * Assume e2fs_ipg is a multiple of NBBY since - * it's a multiple of e2fs_ipb (as we did above). - * Note even (possibly smaller) the last group has the same e2fs_ipg. - */ - i = sblock.e2fs.e2fs_ipg / NBBY; - memset(buf, 0, i); - memset(buf + i, ~0U, sblock.e2fs_bsize - i); - if (cylno == 0) { - /* mark reserved inodes */ - for (i = 1; i < EXT2_FIRSTINO; i++) - setbit(buf, EXT2_INO_INDEX(i)); - } - wtfs(EXT2_FSBTODB(&sblock, gd[cylno].ext2bgd_i_bitmap), - sblock.e2fs_bsize, buf); - - /* - * Initialize inode tables. - * - * Just initialize generation numbers for NFS security. - * XXX: sys/ufs/ext2fs/ext2fs_alloc.c:ext2fs_valloc() seems - * to override these generated numbers. - */ - memset(buf, 0, sblock.e2fs_bsize); - for (i = 0; i < sblock.e2fs_itpg; i++) { - for (j = 0; j < sblock.e2fs_ipb; j++) { - dp = (struct ext2fs_dinode *)(buf + inodesize * j); - /* h2fs32() just for consistency */ - dp->e2di_gen = h2fs32(arc4random()); - } - wtfs(EXT2_FSBTODB(&sblock, gd[cylno].ext2bgd_i_tables + i), - sblock.e2fs_bsize, buf); - } -} - -/* - * Zap possible lingering old superblock data - */ -static void -zap_old_sblock(int sblkoff) -{ - static int cg0_data; - uint32_t oldfs[SBSIZE / sizeof(uint32_t)]; - static const struct fsm { - uint32_t offset; - uint32_t magic; - uint32_t mask; - } fs_magics[] = { - {offsetof(struct ext2fs, e2fs_magic) / 4, E2FS_MAGIC, 0xffff}, - {offsetof(struct ext2fs, e2fs_magic) / 4, - E2FS_MAGIC << 16, 0xffff0000}, - {14, 0xef530000, 0xffff0000}, /* EXT2FS (big) */ - {0x55c / 4, 0x00011954, ~0U}, /* FS_UFS1_MAGIC */ - {0x55c / 4, 0x19540119, ~0U}, /* FS_UFS2_MAGIC */ - {0, 0x70162, ~0U}, /* LFS_MAGIC */ - {.offset = ~0U}, - }; - const struct fsm *fsm; - - if (Nflag) - return; - - /* don't override data before superblock */ - if (sblkoff < SBOFF) - return; - - if (cg0_data == 0) { - cg0_data = - ((daddr_t)sblock.e2fs.e2fs_first_dblock + cgoverhead(0)) * - sblock.e2fs_bsize; - } - - /* Ignore anything that is beyond our filesystem */ - if (sblkoff / sectorsize >= fssize) - return; - /* Zero anything inside our filesystem... */ - if (sblkoff >= sblock.e2fs.e2fs_first_dblock * bsize) { - /* ...unless we will write that area anyway */ - if (sblkoff >= cg0_data) - /* assume iobuf is zero'ed here */ - wtfs(sblkoff / sectorsize, - roundup(SBSIZE, sectorsize), iobuf); - return; - } - - /* - * The sector might contain boot code, so we must validate it - * - * XXX: ext2fs won't preserve data after SBOFF, - * but first_dblock could have a different value. - */ - rdfs(sblkoff / sectorsize, sizeof(oldfs), &oldfs); - for (fsm = fs_magics;; fsm++) { - uint32_t v; - if (fsm->mask == 0) - return; - v = oldfs[fsm->offset]; - if ((v & fsm->mask) == fsm->magic || - (bswap32(v) & fsm->mask) == fsm->magic) - break; - } - - /* Just zap the magic number */ - oldfs[fsm->offset] = 0; - wtfs(sblkoff / sectorsize, sizeof(oldfs), &oldfs); -} - -/* - * uint cgoverhead(uint c) - * - * Return a number of reserved blocks on the specified group. - * XXX: should be shared with src/sbin/fsck_ext2fs/setup.c - */ -uint -cgoverhead(uint c) -{ - uint overh; - - overh = NBLOCK_BLOCK_BITMAP + NBLOCK_INODE_BITMAP + sblock.e2fs_itpg; - - if (sblock.e2fs.e2fs_rev == E2FS_REV0 || - (sblock.e2fs.e2fs_features_rocompat & - EXT2F_ROCOMPAT_SPARSESUPER) == 0 || - cg_has_sb(c) != 0) { - overh += NBLOCK_SUPERBLOCK + sblock.e2fs_ngdb; - - if (sblock.e2fs.e2fs_rev > E2FS_REV0 && - (sblock.e2fs.e2fs_features_compat & - EXT2F_COMPAT_RESIZE) != 0) - overh += sblock.e2fs.e2fs_reserved_ngdb; - } - - return overh; -} - -/* - * Initialize the file system - */ - -#define LOSTDIR /* e2fsck complains if there is no lost+found */ - -#define PREDEFDIR 2 - -#ifdef LOSTDIR -#define PREDEFROOTDIR (PREDEFDIR + 1) -#else -#define PREDEFROOTDIR PREDEFDIR -#endif - -struct ext2fs_direct root_dir[] = { - { EXT2_ROOTINO, 0, 1, 0, "." }, - { EXT2_ROOTINO, 0, 2, 0, ".." }, -#ifdef LOSTDIR - { EXT2_LOSTFOUNDINO, 0, 10, 0, "lost+found" }, -#endif -}; - -#ifdef LOSTDIR -struct ext2fs_direct lost_found_dir[] = { - { EXT2_LOSTFOUNDINO, 0, 1, 0, "." }, - { EXT2_ROOTINO, 0, 2, 0, ".." }, -}; -struct ext2fs_direct pad_dir = { 0, sizeof(struct ext2fs_direct), 0, 0, "" }; -#endif - -int -fsinit(const struct timeval *tv) -{ - struct ext2fs_dinode node; -#ifdef LOSTDIR - uint i, nblks_lostfound, blk; -#endif - - /* - * Initialize the inode for the resizefs feature - */ - if (sblock.e2fs.e2fs_rev > E2FS_REV0 && - (sblock.e2fs.e2fs_features_compat & EXT2F_COMPAT_RESIZE) != 0) - init_resizeino(tv); - - /* - * Initialize the node - */ - -#ifdef LOSTDIR - /* - * Create the lost+found directory - */ - if (sblock.e2fs.e2fs_rev > E2FS_REV0 && - sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE) { - lost_found_dir[0].e2d_type = EXT2_FT_DIR; - lost_found_dir[1].e2d_type = EXT2_FT_DIR; - } - (void)makedir(lost_found_dir, __arraycount(lost_found_dir)); - - /* prepare a bit large directory for preserved files */ - nblks_lostfound = EXT2_LOSTFOUNDSIZE / sblock.e2fs_bsize; - /* ...but only with direct blocks */ - if (nblks_lostfound > EXT2FS_NDADDR) - nblks_lostfound = EXT2FS_NDADDR; - - memset(&node, 0, sizeof(node)); - node.e2di_mode = EXT2_IFDIR | EXT2_LOSTFOUNDUMASK; - node.e2di_uid = geteuid(); - node.e2di_size = sblock.e2fs_bsize * nblks_lostfound; - node.e2di_atime = tv->tv_sec; - node.e2di_ctime = tv->tv_sec; - node.e2di_mtime = tv->tv_sec; - node.e2di_gid = getegid(); - node.e2di_nlink = PREDEFDIR; - /* e2di_nblock is a number of disk blocks, not ext2fs blocks */ - node.e2di_nblock = EXT2_FSBTODB(&sblock, nblks_lostfound); - node.e2di_blocks[0] = alloc(sblock.e2fs_bsize, node.e2di_mode); - if (node.e2di_blocks[0] == 0) { - printf("%s: can't allocate block for lost+found\n", __func__); - return 0; - } - for (i = 1; i < nblks_lostfound; i++) { - blk = alloc(sblock.e2fs_bsize, 0); - if (blk == 0) { - printf("%s: can't allocate blocks for lost+found\n", - __func__); - return 0; - } - node.e2di_blocks[i] = blk; - } - wtfs(EXT2_FSBTODB(&sblock, node.e2di_blocks[0]), - sblock.e2fs_bsize, buf); - pad_dir.e2d_reclen = sblock.e2fs_bsize; - for (i = 1; i < nblks_lostfound; i++) { - memset(buf, 0, sblock.e2fs_bsize); - copy_dir(&pad_dir, (struct ext2fs_direct *)buf); - wtfs(EXT2_FSBTODB(&sblock, node.e2di_blocks[i]), - sblock.e2fs_bsize, buf); - } - iput(&node, EXT2_LOSTFOUNDINO); -#endif - /* - * create the root directory - */ - memset(&node, 0, sizeof(node)); - if (sblock.e2fs.e2fs_rev > E2FS_REV0 && - sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE) { - root_dir[0].e2d_type = EXT2_FT_DIR; - root_dir[1].e2d_type = EXT2_FT_DIR; -#ifdef LOSTDIR - root_dir[2].e2d_type = EXT2_FT_DIR; -#endif - } - node.e2di_mode = EXT2_IFDIR | EXT2_UMASK; - node.e2di_uid = geteuid(); - node.e2di_size = makedir(root_dir, __arraycount(root_dir)); - node.e2di_atime = tv->tv_sec; - node.e2di_ctime = tv->tv_sec; - node.e2di_mtime = tv->tv_sec; - node.e2di_gid = getegid(); - node.e2di_nlink = PREDEFROOTDIR; - /* e2di_nblock is a number of disk block, not ext2fs block */ - node.e2di_nblock = EXT2_FSBTODB(&sblock, 1); - node.e2di_blocks[0] = alloc(node.e2di_size, node.e2di_mode); - if (node.e2di_blocks[0] == 0) { - printf("%s: can't allocate block for root dir\n", __func__); - return 0; - } - wtfs(EXT2_FSBTODB(&sblock, node.e2di_blocks[0]), - sblock.e2fs_bsize, buf); - iput(&node, EXT2_ROOTINO); - return 1; -} - -/* - * Construct a set of directory entries in "buf". - * return size of directory. - */ -int -makedir(struct ext2fs_direct *protodir, int entries) -{ - uint8_t *cp; - uint i, spcleft; - uint dirblksiz; - - dirblksiz = sblock.e2fs_bsize; - memset(buf, 0, dirblksiz); - spcleft = dirblksiz; - for (cp = buf, i = 0; i < entries - 1; i++) { - protodir[i].e2d_reclen = EXT2FS_DIRSIZ(protodir[i].e2d_namlen); - copy_dir(&protodir[i], (struct ext2fs_direct *)cp); - cp += protodir[i].e2d_reclen; - spcleft -= protodir[i].e2d_reclen; - } - protodir[i].e2d_reclen = spcleft; - copy_dir(&protodir[i], (struct ext2fs_direct *)cp); - return dirblksiz; -} - -/* - * Copy a direntry to a buffer, in fs byte order - */ -static void -copy_dir(struct ext2fs_direct *dir, struct ext2fs_direct *dbuf) -{ - - memcpy(dbuf, dir, EXT2FS_DIRSIZ(dir->e2d_namlen)); - dbuf->e2d_ino = h2fs32(dir->e2d_ino); - dbuf->e2d_reclen = h2fs16(dir->e2d_reclen); -} - -/* - * void init_resizeino(const struct timeval *tv); - * - * Initialize the EXT2_RESEIZE_INO inode to preserve - * reserved group descriptor blocks for future growth of this ext2fs. - */ -void -init_resizeino(const struct timeval *tv) -{ - struct ext2fs_dinode node; - uint64_t isize; - uint32_t *dindir_block, *reserved_gdb; - uint nblock, i, cylno, n; - - memset(&node, 0, sizeof(node)); - - /* - * Note this function only prepares required structures for - * future resize. It's a quite different work to implement - * a utility like resize_ext2fs(8) which handles actual - * resize ops even on offline. - * - * Anyway, I'm not sure if there is any documentation about - * this resize ext2fs feature and related data structures, - * and I've written this function based on things what I see - * on some existing implementation and real file system data - * created by existing tools. To be honest, they are not - * so easy to read, so I will try to implement it here without - * any dumb optimization for people who would eventually - * work on "yet another wheel" like resize_ext2fs(8). - */ - - /* - * I'm not sure what type is appropriate for this inode. - * The release notes of e2fsprogs says they changed e2fsck to allow - * IFREG for RESIZEINO since a certain resize tool used it. Hmm. - */ - node.e2di_mode = EXT2_IFREG | EXT2_RESIZEINOUMASK; - node.e2di_uid = geteuid(); - node.e2di_atime = tv->tv_sec; - node.e2di_ctime = tv->tv_sec; - node.e2di_mtime = tv->tv_sec; - node.e2di_gid = getegid(); - node.e2di_nlink = 1; - - /* - * To preserve the reserved group descriptor blocks, - * EXT2_RESIZEINO uses only double indirect reference - * blocks in its inode entries. - * - * All entries for direct, single indirect and triple - * indirect references are left zero'ed. Maybe it's safe - * because no write operation will happen with this inode. - * - * We have to allocate a block for the first level double - * indirect reference block. Indexes of inode entries in - * this first level dindirect block are corresponding to - * indexes of group descriptors including both used (e2fs_ngdb) - * and reserved (e2fs_reserved_ngdb) group descriptor blocks. - * - * Inode entries of indexes for used (e2fs_ngdb) descriptors are - * left zero'ed. Entries for reserved (e2fs_reserved_ngdb) ones - * have block numbers of actual reserved group descriptors - * allocated at block group zero. This means e2fs_reserved_ngdb - * blocks are reserved as the second level dindirect reference - * blocks, and they actually contain block numbers of indirect - * references. It may be safe since they don't have to keep any - * data yet. - * - * Each these second dindirect blocks (i.e. reserved group - * descriptor blocks in the first block group) should have - * block numbers of its backups in all other block groups. - * I.e. reserved_ngdb[0] block in block group 0 contains block - * numbers of resreved_ngdb[0] from group 1 through (e2fs_ncg - 1). - * The number of backups can be determined by the - * EXT2_ROCOMPAT_SPARSESUPER feature and cg_has_sb() macro - * as done in the above initcg() function. - */ - - /* set e2di_size which occupies whole blocks through DINDIR blocks */ - isize = (uint64_t)sblock.e2fs_bsize * EXT2FS_NDADDR + - (uint64_t)sblock.e2fs_bsize * EXT2_NINDIR(&sblock) + - (uint64_t)sblock.e2fs_bsize * EXT2_NINDIR(&sblock) * - EXT2_NINDIR(&sblock); - if (isize > UINT32_MAX && - (sblock.e2fs.e2fs_features_rocompat & - EXT2F_ROCOMPAT_LARGEFILE) == 0) { - /* XXX should enable it here and update all backups? */ - errx(EXIT_FAILURE, "%s: large_file rocompat feature is " - "required to enable resize feature for this filesystem", - __func__); - } - /* upper 32bit is stored into e2di_dacl on REV1 feature */ - node.e2di_size = isize & UINT32_MAX; - node.e2di_dacl = isize >> 32; - -#define SINGLE 0 /* index of single indirect block */ -#define DOUBLE 1 /* index of double indirect block */ -#define TRIPLE 2 /* index of triple indirect block */ - - /* zero out entries for direct references */ - for (i = 0; i < EXT2FS_NDADDR; i++) - node.e2di_blocks[i] = 0; - /* also zero out entries for single and triple indirect references */ - node.e2di_blocks[EXT2FS_NDADDR + SINGLE] = 0; - node.e2di_blocks[EXT2FS_NDADDR + TRIPLE] = 0; - - /* allocate a block for the first level double indirect reference */ - node.e2di_blocks[EXT2FS_NDADDR + DOUBLE] = - alloc(sblock.e2fs_bsize, node.e2di_mode); - if (node.e2di_blocks[EXT2FS_NDADDR + DOUBLE] == 0) - errx(EXIT_FAILURE, "%s: Can't allocate a dindirect block", - __func__); - - /* account this first block */ - nblock = EXT2_FSBTODB(&sblock, 1); - - /* allocate buffer to set data in the dindirect block */ - dindir_block = malloc(sblock.e2fs_bsize); - if (dindir_block == NULL) - errx(EXIT_FAILURE, - "%s: Can't allocate buffer for a dindirect block", - __func__); - - /* allocate buffer to set data in the group descriptor blocks */ - reserved_gdb = malloc(sblock.e2fs_bsize); - if (reserved_gdb == NULL) - errx(EXIT_FAILURE, - "%s: Can't allocate buffer for group descriptor blocks", - __func__); - - /* - * Setup block entries in the first level dindirect blocks - */ - for (i = 0; i < sblock.e2fs_ngdb; i++) { - /* no need to handle used group descriptor blocks */ - dindir_block[i] = 0; - } - for (; i < sblock.e2fs_ngdb + sblock.e2fs.e2fs_reserved_ngdb; i++) { - /* - * point reserved group descriptor block in the first - * (i.e. master) block group - * - * XXX: e2fsprogs seem to use "(i % EXT2_NINDIR(&sblock))" here - * to store maximum EXT2_NINDIR(&sblock) reserved gdbs. - * I'm not sure what will be done on future filesystem - * shrink in that case on their way. - */ - if (i >= EXT2_NINDIR(&sblock)) - errx(EXIT_FAILURE, "%s: too many reserved " - "group descriptors (%u) for resize inode", - __func__, sblock.e2fs.e2fs_reserved_ngdb); - dindir_block[i] = - h2fs32(cgbase(&sblock, 0) + NBLOCK_SUPERBLOCK + i); - - /* - * Setup block entries in the second dindirect blocks - * (which are primary reserved group descriptor blocks) - * to point their backups. - */ - for (n = 0, cylno = 1; cylno < sblock.e2fs_ncg; cylno++) { - /* skip block groups without backup */ - if ((sblock.e2fs.e2fs_features_rocompat & - EXT2F_ROCOMPAT_SPARSESUPER) != 0 && - cg_has_sb(cylno) == 0) - continue; - - if (n >= EXT2_NINDIR(&sblock)) - errx(EXIT_FAILURE, "%s: too many block groups " - "for the resize feature", __func__); - /* - * These blocks are already reserved in - * initcg() so no need to use alloc() here. - */ - reserved_gdb[n++] = h2fs32(cgbase(&sblock, cylno) + - NBLOCK_SUPERBLOCK + i); - nblock += EXT2_FSBTODB(&sblock, 1); - } - for (; n < EXT2_NINDIR(&sblock); n++) - reserved_gdb[n] = 0; - - /* write group descriptor block as the second dindirect refs */ - wtfs(EXT2_FSBTODB(&sblock, fs2h32(dindir_block[i])), - sblock.e2fs_bsize, reserved_gdb); - nblock += EXT2_FSBTODB(&sblock, 1); - } - for (; i < EXT2_NINDIR(&sblock); i++) { - /* leave trailing entries unallocated */ - dindir_block[i] = 0; - } - free(reserved_gdb); - - /* finally write the first level dindirect block */ - wtfs(EXT2_FSBTODB(&sblock, node.e2di_blocks[EXT2FS_NDADDR + DOUBLE]), - sblock.e2fs_bsize, dindir_block); - free(dindir_block); - - node.e2di_nblock = nblock; - iput(&node, EXT2_RESIZEINO); -} - -/* - * uint32_t alloc(uint32_t size, uint16_t mode) - * - * Allocate a block (from cylinder group 0) - * Reference: src/sys/ufs/ext2fs/ext2fs_alloc.c:ext2fs_alloccg() - */ -uint32_t -alloc(uint32_t size, uint16_t mode) -{ - uint32_t loc, bno; - uint8_t *bbp; - uint len, map, i; - - if (gd[0].ext2bgd_nbfree == 0) - return 0; - - if (size > sblock.e2fs_bsize) - return 0; - - bbp = malloc(sblock.e2fs_bsize); - if (bbp == NULL) - return 0; - rdfs(EXT2_FSBTODB(&sblock, gd[0].ext2bgd_b_bitmap), - sblock.e2fs_bsize, bbp); - - /* XXX: kernel uses e2fs_fpg here */ - len = sblock.e2fs.e2fs_bpg / NBBY; - -#if 0 /* no need block allocation for root or lost+found dir */ - for (loc = 0; loc < len; loc++) { - if (bbp[loc] == 0) { - bno = loc * NBBY; - goto gotit; - } - } -#endif - - loc = skpc(~0U, len, bbp); - if (loc == 0) { - free(bbp); - return 0; - } - loc = len - loc; - map = bbp[loc]; - bno = loc * NBBY; - for (i = 0; i < NBBY; i++, bno++) { - if ((map & (1 << i)) == 0) - goto gotit; - } - free(bbp); - return 0; - - gotit: - if (isset(bbp, bno)) - errx(EXIT_FAILURE, "%s: inconsistent bitmap", __func__); - - setbit(bbp, bno); - wtfs(EXT2_FSBTODB(&sblock, gd[0].ext2bgd_b_bitmap), - sblock.e2fs_bsize, bbp); - free(bbp); - /* XXX: modified group descriptors won't be written into backups */ - gd[0].ext2bgd_nbfree--; - if ((mode & EXT2_IFDIR) != 0) - gd[0].ext2bgd_ndirs++; - sblock.e2fs.e2fs_fbcount--; - - return sblock.e2fs.e2fs_first_dblock + bno; -} - -/* - * void iput(struct ext2fs_dinode *ip, ino_t ino) - * - * Put an inode entry into the corresponding table. - */ -static void -iput(struct ext2fs_dinode *ip, ino_t ino) -{ - daddr_t d; - uint c, i; - struct ext2fs_dinode *dp; - uint8_t *bp; - - bp = malloc(sblock.e2fs_bsize); - if (bp == NULL) - errx(EXIT_FAILURE, "%s: can't allocate buffer for inode", - __func__); - - /* - * Reserved inodes are allocated and accounted in initcg() - * so skip checks of the bitmap and allocation for them. - */ - if (ino >= EXT2_FIRSTINO) { - c = ino_to_cg(&sblock, ino); - - /* sanity check */ - if (gd[c].ext2bgd_nifree == 0) - errx(EXIT_FAILURE, - "%s: no free inode %" PRIu64 " in block group %u", - __func__, (uint64_t)ino, c); - - /* update inode bitmap */ - rdfs(EXT2_FSBTODB(&sblock, gd[0].ext2bgd_i_bitmap), - sblock.e2fs_bsize, bp); - - /* more sanity */ - if (isset(bp, EXT2_INO_INDEX(ino))) - errx(EXIT_FAILURE, "%s: inode %" PRIu64 - " already in use", __func__, (uint64_t)ino); - setbit(bp, EXT2_INO_INDEX(ino)); - wtfs(EXT2_FSBTODB(&sblock, gd[0].ext2bgd_i_bitmap), - sblock.e2fs_bsize, bp); - gd[c].ext2bgd_nifree--; - sblock.e2fs.e2fs_ficount--; - } - - if (ino >= sblock.e2fs.e2fs_ipg * sblock.e2fs_ncg) - errx(EXIT_FAILURE, "%s: inode value out of range (%" PRIu64 - ")", __func__, (uint64_t)ino); - - /* update an inode entry in the table */ - d = EXT2_FSBTODB(&sblock, ino_to_fsba(&sblock, ino)); - rdfs(d, sblock.e2fs_bsize, bp); - - dp = (struct ext2fs_dinode *)(bp + - inodesize * ino_to_fsbo(&sblock, ino)); - e2fs_isave(ip, dp); - /* e2fs_i_bswap() doesn't swap e2di_blocks addrs */ - if ((ip->e2di_mode & EXT2_IFMT) != EXT2_IFLNK) { - for (i = 0; i < EXT2FS_NDADDR + EXT2FS_NIADDR; i++) - dp->e2di_blocks[i] = h2fs32(ip->e2di_blocks[i]); - } - /* h2fs32() just for consistency */ - dp->e2di_gen = h2fs32(arc4random()); - - wtfs(d, sblock.e2fs_bsize, bp); - free(bp); -} - -/* - * Read a block from the file system - */ -void -rdfs(daddr_t bno, int size, void *bf) -{ - int n; - off_t offset; - - offset = bno; - n = pread(fsi, bf, size, offset * sectorsize); - if (n != size) - err(EXIT_FAILURE, "%s: read error for sector %" PRId64, - __func__, (int64_t)bno); -} - -/* - * Write a block to the file system - */ -void -wtfs(daddr_t bno, int size, void *bf) -{ - int n; - off_t offset; - - if (Nflag) - return; - offset = bno; - n = pwrite(fso, bf, size, offset * sectorsize); - if (n != size) - err(EXIT_FAILURE, "%s: write error for sector %" PRId64, - __func__, (int64_t)bno); -} - -int -ilog2(uint val) -{ - - if (val == 0 || !powerof2(val)) - errx(EXIT_FAILURE, "%s: %u is not a power of 2", - __func__, val); - - return ffs(val) - 1; -} - -/* - * int skpc(int mask, size_t size, uint8_t *cp) - * - * Locate an unsigned character of value mask inside cp[]. - * (from src/sys/lib/libkern/skpc.c) - */ -int -skpc(int mask, size_t size, uint8_t *cp) -{ - uint8_t *end; - - end = &cp[size]; - while (cp < end && *cp == (uint8_t)mask) - cp++; - - return end - cp; -} diff --git a/sbin/newfs_ext2fs/newfs_ext2fs.8 b/sbin/newfs_ext2fs/newfs_ext2fs.8 deleted file mode 100644 index 9d87ebc91..000000000 --- a/sbin/newfs_ext2fs/newfs_ext2fs.8 +++ /dev/null @@ -1,326 +0,0 @@ -.\" $NetBSD: newfs_ext2fs.8,v 1.11 2010/02/25 13:09:17 tsutsui Exp $ -.\" -.\" Copyright (c) 1983, 1987, 1991, 1993, 1994 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)newfs.8 8.6 (Berkeley) 5/3/95 -.\" -.Dd March 1, 2009 -.Dt NEWFS_EXT2FS 8 -.Os -.Sh NAME -.Nm newfs_ext2fs -.Nd construct a new ext2 file system -.Sh SYNOPSIS -.Nm -.Op Fl FINZ -.Op Fl b Ar block-size -.Op Fl D Ar inodesize -.Op Fl f Ar frag-size -.Op Fl i Ar bytes-per-inode -.Op Fl m Ar free-space -.Op Fl n Ar inodes -.Op Fl O Ar filesystem-format -.Op Fl S Ar sector-size -.Op Fl s Ar size -.Op Fl V Ar verbose -.Op Fl v Ar volname -.Ar special -.Sh DESCRIPTION -.Nm -is used to initialize and clear ext2 file systems before first use. -Before running -.Nm -the disk must be labeled using -.Xr disklabel 8 . -.Nm -builds a file system on the specified special device -basing its defaults on the information in the disk label. -Typically the defaults are reasonable, however -.Nm -has numerous options to allow the defaults to be selectively overridden. -.Pp -Options with numeric arguments may contain an optional (case-insensitive) -suffix: -.Bl -tag -width 3n -offset indent -compact -.It b -Bytes; causes no modification. -(Default) -.It k -Kilo; multiply the argument by 1024. -.It m -Mega; multiply the argument by 1048576. -.It g -Giga; multiply the argument by 1073741824. -.El -.Pp -The following options define the general layout policies. -.Bl -tag -width Fl -.It Fl b Ar block-size -The block size of the file system, in bytes. -It must be a power of two. -The smallest allowable size is 1024 bytes. -The default size depends upon the size of the file system: -.Pp -.Bl -tag -width "file system size" -compact -offset indent -.It Sy "file system size" -.Ar block-size -.It \*[Lt]= 512 MB -1 KB -.It \*[Gt] 512 MB -4 KB -.El -.It Fl D Ar inodesize -Set the inode size. -Defaults to 128, and can also be set to 256 for -compatibility with ext4. -.It Fl F -Create a file system image in -.Ar special . -The file system size needs to be specified with -.Dq Fl s Ar size . -No attempts to use or update the disk label will be made. -.It Fl f Ar frag-size -The fragment size of the file system in bytes. -It must be the same with blocksize because the current ext2fs -implementation doesn't support fragmentation. -.It Fl I -Do not require that the file system type listed in the disk label is -.Ql Linux\ Ext2 . -.It Fl i Ar bytes-per-inode -This specifies the density of inodes in the file system. -If fewer inodes are desired, a larger number should be used; -to create more inodes a smaller number should be given. -.It Fl m Ar free-space -The percentage of space reserved from normal users; the minimum free -space threshold. -The default value used is 5%. -.It Fl N -Causes the file system parameters to be printed out -without really creating the file system. -.It Fl n Ar inodes -This specifies the number of inodes for the file system. -If both -.Fl i -and -.Fl n -are specified then -.Fl n -takes precedence. -The default number of inodes is calculated from a number of blocks in -the file system. -.It Fl O Ar filesystem-format -Select the filesystem-format. -.Bl -tag -width 3n -offset indent -compact -.It 0 -.Ql GOOD_OLD_REV ; -this option is primarily used to build root file systems that can be -understood by old or dumb firmwares for bootstrap. -(default) -.It 1 -.Ql DYNAMIC_REV ; -various extended (and sometimes incompatible) features are enabled -(though not all features are supported on -.Nx ) . -Currently only the following features are supported: -.Bl -tag -width "SPARSESUPER" -offset indent -compact -.It RESIZE -Prepare some reserved structures which enable future file system resizing. -.It FTYPE -Store file types in directory entries to improve performance. -.It SPARSESUPER -Prepare superblock backups for the -.Xr fsck_ext2fs 8 -utility on not all but sparse block groups. -.It LARGEFILE -Enable files larger than 2G bytes. -.El -.El -.It Fl s Ar size -The size of the file system in sectors. -An -.Sq s -suffix will be interpreted as the number of sectors (the default). -All other suffixes are interpreted as per other numeric arguments, -except that the number is converted into sectors by dividing by the -sector size (as specified by -.Fl S Ar secsize ) -after suffix interpretation. -.Pp -If no -.Fl s Ar size -is specified then the filesystem size defaults to that of the partition, or, -if -.Fl F -is specified, the existing file. -.Pp -If -.Ar size -is negative the specified size is subtracted from the default size -(reserving space at the end of the partition). -.It Fl V Ar verbose -This controls the amount of information written to stdout: -.Bl -tag -width 3n -offset indent -compact -.It 0 -No output. -.It 1 -Overall size and cylinder group details. -.It 2 -A progress bar (dots ending at right hand margin). -.It 3 -The first few super-block backup sector numbers are displayed before the -progress bar. -.It 4 -All the super-block backup sector numbers are displayed (no progress bar). -.El -The default is 3. -If -.Fl N -is specified -.Nm -stops before outputting the progress bar. -.It Fl v Ar volname -This specifies a volume name for the file system. -.It Fl Z -Pre-zeros the file system image created with -.Fl F . -This is necessary if the image is to be used by -.Xr vnd 4 -(which doesn't support file systems with -.Sq holes ) . -.El -.Pp -The following option overrides the standard sizes for the disk geometry. -The default value is taken from the disk label. -Changing this default is useful only when using -.Nm -to build a file system whose raw image will eventually be used on a -different type of disk than the one on which it is initially created -(for example on a write-once disk). -Note that changing this value from its default will make it impossible for -.Xr fsck_ext2fs 8 -to find the alternative superblocks if the standard superblock is lost. -.Bl -tag -width Fl -.It Fl S Ar sector-size -The size of a sector in bytes (almost never anything but 512). -Defaults to 512. -.El -.Sh NOTES -There is no option to specify the metadata byte order on the file system -to be created because the native ext2 file system is always little endian -even on big endian hosts. -.Pp -The file system is created with -.Sq random -inode generation numbers to improve NFS security. -.Pp -The owner and group IDs of the root node and reserved blocks of the new -file system are set to the effective UID and GID of the user initializing -the file system. -.Pp -For the -.Nm -command to succeed, -the disk label should first be updated such that the fstype field for the -partition is set to -.Ql Linux\ Ext2 , -unless -.Fl F -or -.Fl I -is used. -.Pp -.\" To create and populate a filesystem image within a file use the -.\" .Xr makefs 8 -.\" utility. -.\" .Pp -The partition size is found using -.Xr fstat 2 , -not by inspecting the disk label. -The block size and fragment size will be written back to the disk label -only if the last character of -.Ar special -references the same partition as the minor device number. -.Sh SEE ALSO -.Xr fstat 2 , -.Xr disklabel 5 , -.Xr disktab 5 , -.Xr fs 5 , -.Xr disklabel 8 , -.Xr diskpart 8 , -.\" .Xr dumpfs 8 , -.\" .Xr format 8 , -.Xr fsck_ext2fs 8 , -.\" .Xr makefs 8 , -.Xr mount 8 , -.Xr mount_ext2fs 8 , -.Xr newfs 8 -.Rs -.%A Remy Card -.%A Theodore Ts'o -.%A Stephen Tweedie -.%T "Design and Implementation of the Second Extended Filesystem" -.%J "The Proceedings of the First Dutch International Symposium on Linux" -.%U http://e2fsprogs.sourceforge.net/ext2intro.html -.Re -.Sh HISTORY -The -.Nm -command first appeared in -.Nx 5.0 . -.Sh AUTHORS -The -.Nm -command was written by -.An Izumi Tsutsui -.Aq tsutsui@NetBSD.org . -.Sh BUGS -The -.Nm -command is still experimental and there are few sanity checks. -.Pp -The -.Nm -command doesn't have options to specify each REV1 file system feature -independently. -.Pp -The -.Nm -command doesn't support the bad block list accounted by the bad blocks inode. -.Pp -Many newer ext2 file system features (especially journaling) are -not supported yet. -.Pp -Some features in file systems created by the -.Nm -command might not be recognized properly by the -.Xr fsck_ext2fs 8 -utility. -.Pp -There is no native tool in the -.Nx -distribution for resizing ext2 file systems yet. diff --git a/sbin/newfs_ext2fs/newfs_ext2fs.c b/sbin/newfs_ext2fs/newfs_ext2fs.c deleted file mode 100644 index 32e6d7e89..000000000 --- a/sbin/newfs_ext2fs/newfs_ext2fs.c +++ /dev/null @@ -1,532 +0,0 @@ -/* $NetBSD: newfs_ext2fs.c,v 1.9 2013/10/19 01:09:59 christos Exp $ */ - -/* - * Copyright (c) 1983, 1989, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1983, 1989, 1993, 1994\ - The Regents of the University of California. All rights reserved."); -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)newfs.c 8.13 (Berkeley) 5/1/95"; -#else -__RCSID("$NetBSD: newfs_ext2fs.c,v 1.9 2013/10/19 01:09:59 christos Exp $"); -#endif -#endif /* not lint */ - -/* - * newfs: friendly front end to mke2fs - */ -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(__minix) -#include -#endif /* !defined(__minix) */ - -#include "extern.h" -#include "partutil.h" - -static int64_t strsuftoi64(const char *, const char *, int64_t, int64_t, int *); -static void usage(void) __dead; - -/* - * For file systems smaller than SMALL_FSSIZE we use the S_DFL_* defaults, - * otherwise if less than MEDIUM_FSSIZE use M_DFL_*, otherwise use - * L_DFL_*. - */ -#define SMALL_FSSIZE ((4 * 1024 * 1024) / sectorsize) /* 4MB */ -#if !defined(__minix) -#define S_DFL_BSIZE 1024 -#else -#define S_DFL_BSIZE 4096 -#endif /* !defined(__minix) */ -#define MEDIUM_FSSIZE ((512 * 1024 * 1024) / sectorsize) /* 512MB */ -#if !defined(__minix) -#define M_DFL_BSIZE 1024 -#else -#define M_DFL_BSIZE 4096 -#endif /* !defined(__minix) */ -#define L_DFL_BSIZE 4096 - -/* - * Each file system has a number of inodes statically allocated. - * We allocate one inode slot per 2, 4, or 8 blocks, expecting this - * to be far more than we will ever need. - */ -#define S_DFL_NINODE(blocks) ((blocks) / 8) -#define M_DFL_NINODE(blocks) ((blocks) / 4) -#define L_DFL_NINODE(blocks) ((blocks) / 2) - -/* - * Default sector size. - */ -#define DFL_SECSIZE 512 - -int Nflag; /* run without writing file system */ -int Oflag = 0; /* format as conservative REV0 by default */ -int verbosity; /* amount of printf() output */ -#define DEFAULT_VERBOSITY 3 /* 4 is traditional behavior of newfs(8) */ -int64_t fssize; /* file system size */ -uint sectorsize; /* bytes/sector */ -uint16_t inodesize = EXT2_REV0_DINODE_SIZE; /* inode size */ -uint fsize = 0; /* fragment size */ -uint bsize = 0; /* block size */ -uint minfree = MINFREE; /* free space threshold */ -uint density; /* number of bytes per inode */ -uint num_inodes; /* number of inodes (overrides density) */ -char *volname = NULL; /* volume name */ - -#if !defined(__minix) -static char *disktype = NULL; -#endif /* !defined(__minix) */ -static char device[MAXPATHLEN]; - -#if !defined(__minix) -static const char lmsg[] = "%s: can't read disk label"; -#endif /* !defined(__minix) */ - -int -main(int argc, char *argv[]) -{ -#if !defined(__minix) - struct disk_geom geo; - struct dkwedge_info dkw; -#else - u64_t minix_fssize; -#endif /* !defined(__minix) */ - struct statvfs *mp; - struct stat sb; - int ch, fsi, fso, len, n, Fflag, Iflag, Zflag; - char *s1, *s2, *special; - const char *opstring; - int byte_sized; - uint blocks; /* number of blocks */ - - fsi = fso = -1; - Fflag = Iflag = Zflag = 0; - verbosity = -1; -#if !defined(__minix) - opstring = "D:FINO:S:V:Zb:f:i:l:m:n:s:v:"; -#else - opstring = "D:FINO:S:V:Zb:f:i:l:m:n:s:v:B:"; -#endif /* !defined(__minix) */ - byte_sized = 0; - while ((ch = getopt(argc, argv, opstring)) != -1) - switch (ch) { - case 'D': - inodesize = (uint16_t)strtol(optarg, &s1, 0); - if (*s1 || (inodesize != 128 && inodesize != 256)) - errx(1, "Bad inode size %d " - "(only 128 and 256 supported)", inodesize); - break; - case 'F': - Fflag = 1; - break; -#if !defined(__minix) - case 'I': - Iflag = 1; - break; -#endif /* !defined(__minix) */ - case 'N': - Nflag = 1; - if (verbosity == -1) - verbosity = DEFAULT_VERBOSITY; - break; - case 'O': - Oflag = strsuftoi64("format", optarg, 0, 1, NULL); - break; - case 'S': - /* - * XXX: - * non-512 byte sectors almost certainly don't work. - */ - sectorsize = strsuftoi64("sector size", - optarg, 512, 65536, NULL); - if (!powerof2(sectorsize)) - errx(EXIT_FAILURE, - "sector size `%s' is not a power of 2.", - optarg); - break; - case 'V': - verbosity = strsuftoi64("verbose", optarg, 0, 4, NULL); - break; -#if !defined(__minix) - case 'Z': - Zflag = 1; - break; -#else - case 'B': -#endif /* !defined(__minix) */ - case 'b': - bsize = strsuftoi64("block size", - optarg, MINBSIZE, EXT2_MAXBSIZE, NULL); - break; - case 'f': - fsize = strsuftoi64("fragment size", - optarg, MINBSIZE, EXT2_MAXBSIZE, NULL); - break; - case 'i': - density = strsuftoi64("bytes per inode", - optarg, 1, INT_MAX, NULL); - break; - case 'm': - minfree = strsuftoi64("free space %", - optarg, 0, 99, NULL); - break; - case 'n': - num_inodes = strsuftoi64("number of inodes", - optarg, 1, INT_MAX, NULL); - break; - case 's': - fssize = strsuftoi64("file system size", - optarg, INT64_MIN, INT64_MAX, &byte_sized); - break; - case 'v': - volname = optarg; - if (volname[0] == '\0') - errx(EXIT_FAILURE, - "Volume name cannot be zero length"); - break; - case '?': - default: - usage(); - } - argc -= optind; - argv += optind; - - if (verbosity == -1) - /* Default to showing cg info */ - verbosity = DEFAULT_VERBOSITY; - - if (argc != 1) - usage(); - - memset(&sb, 0, sizeof(sb)); -#if !defined(__minix) - memset(&dkw, 0, sizeof(dkw)); -#endif /* !defined(__minix) */ - special = argv[0]; - if (Fflag) { - int fl; - /* - * It's a file system image - * no label, use fixed default for sectorsize. - */ - if (sectorsize == 0) - sectorsize = DFL_SECSIZE; - - /* creating image in a regular file */ - if (Nflag) - fl = O_RDONLY; - else { - if (fssize > 0) - fl = O_RDWR | O_CREAT; - else - fl = O_RDWR; - } - fsi = open(special, fl, 0777); - if (fsi == -1) - err(EXIT_FAILURE, "can't open file %s", special); - if (fstat(fsi, &sb) == -1) - err(EXIT_FAILURE, "can't fstat opened %s", special); - if (!Nflag) - fso = fsi; - } else { /* !Fflag */ - fsi = opendisk(special, O_RDONLY, device, sizeof(device), 0); - special = device; - if (fsi < 0 || fstat(fsi, &sb) == -1) - err(EXIT_FAILURE, "%s: open for read", special); - - if (!Nflag) { - fso = open(special, O_WRONLY, 0); - if (fso < 0) - err(EXIT_FAILURE, - "%s: open for write", special); - - /* Bail if target special is mounted */ - n = getmntinfo(&mp, MNT_NOWAIT); - if (n == 0) - err(EXIT_FAILURE, "%s: getmntinfo", special); - - len = sizeof(_PATH_DEV) - 1; - s1 = special; - if (strncmp(_PATH_DEV, s1, len) == 0) - s1 += len; - - while (--n >= 0) { - s2 = mp->f_mntfromname; - if (strncmp(_PATH_DEV, s2, len) == 0) { - s2 += len - 1; - *s2 = 'r'; - } - if (strcmp(s1, s2) == 0 || - strcmp(s1, &s2[1]) == 0) - errx(EXIT_FAILURE, - "%s is mounted on %s", - special, mp->f_mntonname); - ++mp; - } - } - -#if !defined(__minix) - if (getdiskinfo(special, fsi, disktype, &geo, &dkw) == -1) - errx(EXIT_FAILURE, lmsg, special); - - if (sectorsize == 0) { - sectorsize = geo.dg_secsize; - if (sectorsize <= 0) - errx(EXIT_FAILURE, "no default sector size"); - } - - if (dkw.dkw_parent[0]) { - if (dkw.dkw_size == 0) - errx(EXIT_FAILURE, - "%s partition is unavailable", special); - - if (!Iflag) { - static const char m[] = - "%s partition type is not `%s' (or use -I)"; - if (strcmp(dkw.dkw_ptype, DKW_PTYPE_EXT2FS)) - errx(EXIT_FAILURE, m, - special, "Linux Ext2"); - } - } -#else - if(minix_sizeup(special, &minix_fssize) < 0) - errx(EXIT_FAILURE, "minix_sizeup failed"); - - fssize = minix_fssize; - byte_sized = 1; - - if (sectorsize == 0) - sectorsize = 512; -#endif /* !defined(__minix) */ - } - - if (byte_sized) - fssize /= sectorsize; -#if !defined(__minix) - if (fssize <= 0) { - if (sb.st_size != 0) - fssize += sb.st_size / sectorsize; - else - fssize += dkw.dkw_size; - if (fssize <= 0) - errx(EXIT_FAILURE, - "Unable to determine file system size"); - } - - if (dkw.dkw_parent[0] && fssize > dkw.dkw_size) - errx(EXIT_FAILURE, - "size %" PRIu64 " exceeds maximum file system size on " - "`%s' of %" PRIu64 " sectors", - fssize, special, dkw.dkw_size); -#endif /* !defined(__minix) */ - - /* XXXLUKEM: only ftruncate() regular files ? (dsl: or at all?) */ - if (Fflag && fso != -1 - && ftruncate(fso, (off_t)fssize * sectorsize) == -1) - err(1, "can't ftruncate %s to %" PRId64, special, fssize); - -#if !defined(__minix) - if (Zflag && fso != -1) { /* pre-zero (and de-sparce) the file */ - char *buf; - int bufsize, i; - off_t bufrem; - struct statvfs sfs; - - if (fstatvfs(fso, &sfs) == -1) { - warn("can't fstatvfs `%s'", special); - bufsize = 8192; - } else - bufsize = sfs.f_iosize; - - if ((buf = calloc(1, bufsize)) == NULL) - err(1, "can't malloc buffer of %d", - bufsize); - bufrem = fssize * sectorsize; - if (verbosity > 0) - printf("Creating file system image in `%s', " - "size %" PRId64 " bytes, in %d byte chunks.\n", - special, bufrem, bufsize); - while (bufrem > 0) { - i = write(fso, buf, MIN(bufsize, bufrem)); - if (i == -1) - err(1, "writing image"); - bufrem -= i; - } - free(buf); - } -#endif /* !defined(__minix) */ - - /* Sort out fragment and block sizes */ - if (bsize == 0) { - bsize = fsize; - if (bsize == 0) { - if (fssize < SMALL_FSSIZE) - bsize = S_DFL_BSIZE; - else if (fssize < MEDIUM_FSSIZE) - bsize = M_DFL_BSIZE; - else - bsize = L_DFL_BSIZE; - } - } - if (fsize == 0) - fsize = bsize; - - blocks = fssize * sectorsize / bsize; - - if (num_inodes == 0) { - if (density != 0) - num_inodes = fssize / density; - else { - if (fssize < SMALL_FSSIZE) - num_inodes = S_DFL_NINODE(blocks); - else if (fssize < MEDIUM_FSSIZE) - num_inodes = M_DFL_NINODE(blocks); - else - num_inodes = L_DFL_NINODE(blocks); - } - } - mke2fs(special, fsi, fso); - - if (fsi != -1) - close(fsi); - if (fso != -1 && fso != fsi) - close(fso); - exit(EXIT_SUCCESS); -} - -static int64_t -strsuftoi64(const char *desc, const char *arg, int64_t min, int64_t max, - int *num_suffix) -{ - int64_t result, r1; - int shift = 0; - char *ep; - - errno = 0; - r1 = strtoll(arg, &ep, 10); - if (ep[0] != '\0' && ep[1] != '\0') - errx(EXIT_FAILURE, - "%s `%s' is not a valid number.", desc, arg); - switch (ep[0]) { - case '\0': - case 's': - case 'S': - if (num_suffix != NULL) - *num_suffix = 0; - break; - case 'g': - case 'G': - shift += 10; - /* FALLTHROUGH */ - case 'm': - case 'M': - shift += 10; - /* FALLTHROUGH */ - case 'k': - case 'K': - shift += 10; - /* FALLTHROUGH */ - case 'b': - case 'B': - if (num_suffix != NULL) - *num_suffix = 1; - break; - default: - errx(EXIT_FAILURE, - "`%s' is not a valid suffix for %s.", ep, desc); - } - result = r1 << shift; - if (errno == ERANGE || result >> shift != r1) - errx(EXIT_FAILURE, - "%s `%s' is too large to convert.", desc, arg); - if (result < min) - errx(EXIT_FAILURE, - "%s `%s' (%" PRId64 ") is less than the minimum (%" - PRId64 ").", desc, arg, result, min); - if (result > max) - errx(EXIT_FAILURE, - "%s `%s' (%" PRId64 ") is greater than the maximum (%" - PRId64 ").", desc, arg, result, max); - return result; -} - -static const char help_strings[] = - "\t-b bsize\tblock size\n" - "\t-D inodesize\tsize of an inode in bytes (128 or 256)\n" - "\t-F \t\tcreate file system image in regular file\n" - "\t-f fsize\tfragment size\n" - "\t-I \t\tdo not check that the file system type is `Linux Ext2'\n" - "\t-i density\tnumber of bytes per inode\n" - "\t-m minfree\tminimum free space %\n" - "\t-N \t\tdo not create file system, just print out parameters\n" - "\t-n inodes\tnumber of inodes (overrides -i density)\n" - "\t-O N\t\tfilesystem revision: 0 ==> REV0, 1 ==> REV1 (default 0)\n" - "\t-S secsize\tsector size\n" - "\t-s fssize\tfile system size (sectors)\n" - "\t-V verbose\toutput verbosity: 0 ==> none, 4 ==> max\n" - "\t-v volname\text2fs volume name\n" - "\t-Z \t\tpre-zero the image file\n"; - -static void -usage(void) -{ - - fprintf(stderr, - "usage: %s [ fsoptions ] special-device\n", getprogname()); - fprintf(stderr, "where fsoptions are:\n"); - fprintf(stderr, "%s", help_strings); - - exit(EXIT_FAILURE); -} diff --git a/sbin/nologin/Makefile b/sbin/nologin/Makefile deleted file mode 100644 index d8fecf97b..000000000 --- a/sbin/nologin/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# $NetBSD: Makefile,v 1.6 1997/03/24 22:17:27 christos Exp $ -# @(#)Makefile 8.2 (Berkeley) 4/22/94 - -MAN= nologin.8 -SCRIPTS=nologin.sh - -.include diff --git a/sbin/nologin/nologin.8 b/sbin/nologin/nologin.8 deleted file mode 100644 index 87e13b26a..000000000 --- a/sbin/nologin/nologin.8 +++ /dev/null @@ -1,58 +0,0 @@ -.\" $NetBSD: nologin.8,v 1.10 2016/09/12 05:23:32 sevan Exp $ -.\" -.\" Copyright (c) 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)nologin.8 8.1 (Berkeley) 6/19/93 -.\" -.Dd September 12, 2016 -.Dt NOLOGIN 8 -.Os -.Sh NAME -.Nm nologin -.Nd politely refuse a login -.Sh SYNOPSIS -.Nm -.Sh DESCRIPTION -.Nm -displays a message that an account is not available and -returns a non-zero exit code. -It is intended as a replacement shell field for accounts that -have been disabled. -.Sh SEE ALSO -.Xr login 1 -.Sh HISTORY -The -.Nm -command appeared in -.Bx 4.4 , -a free re-implementation was contributed in -.Nx 1.5 -to avoid bloat through the copyright comment. -.Sh AUTHORS -Re-implementation by -.An Hubert Feyrer Aq Mt hubertf@NetBSD.org . diff --git a/sbin/ping/ping_hostops.c b/sbin/ping/ping_hostops.c deleted file mode 100644 index 72b1f82fb..000000000 --- a/sbin/ping/ping_hostops.c +++ /dev/null @@ -1,53 +0,0 @@ -/* $NetBSD: ping_hostops.c,v 1.2 2011/03/11 09:59:56 pooka Exp $ */ - -/* - * Copyright (c) 2010 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifndef lint -__RCSID("$NetBSD: ping_hostops.c,v 1.2 2011/03/11 09:59:56 pooka Exp $"); -#endif /* !lint */ - -#include -#include -#include - -#include -#include - -#include "prog_ops.h" - -const struct prog_ops prog_ops = { - .op_socket = socket, - .op_setsockopt = setsockopt, - .op_shutdown = shutdown, - .op_poll = poll, - .op_recvfrom = recvfrom, - .op_sendto = sendto, - .op_close = close, - .op_getuid = getuid, - .op_setuid = setuid, -}; diff --git a/sbin/ping/prog_ops.h b/sbin/ping/prog_ops.h deleted file mode 100644 index ccc5a7066..000000000 --- a/sbin/ping/prog_ops.h +++ /dev/null @@ -1,79 +0,0 @@ -/* $NetBSD: prog_ops.h,v 1.3 2011/03/11 09:59:56 pooka Exp $ */ - -/* - * Copyright (c) 2010 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _PROG_OPS_H_ -#define _PROG_OPS_H_ - -#include - -#ifndef CRUNCHOPS -struct prog_ops { - int (*op_init)(void); - - int (*op_socket)(int, int, int); - int (*op_setsockopt)(int, int, int, const void *, socklen_t); - int (*op_shutdown)(int, int); - - int (*op_poll)(struct pollfd *, nfds_t, int); - - ssize_t (*op_recvfrom)(int, void *, size_t, int, - struct sockaddr *, socklen_t *); - ssize_t (*op_sendto)(int, const void *, size_t, int, - const struct sockaddr *, socklen_t); - - int (*op_close)(int); - - uid_t (*op_getuid)(void); - int (*op_setuid)(uid_t); -}; -extern const struct prog_ops prog_ops; - -#define prog_init prog_ops.op_init -#define prog_socket prog_ops.op_socket -#define prog_setsockopt prog_ops.op_setsockopt -#define prog_shutdown prog_ops.op_shutdown -#define prog_poll prog_ops.op_poll -#define prog_recvfrom prog_ops.op_recvfrom -#define prog_sendto prog_ops.op_sendto -#define prog_close prog_ops.op_close -#define prog_getuid prog_ops.op_getuid -#define prog_setuid prog_ops.op_setuid -#else -#define prog_init ((int (*)(void))NULL) -#define prog_socket socket -#define prog_setsockopt setsockopt -#define prog_shutdown shutdown -#define prog_poll poll -#define prog_recvfrom recvfrom -#define prog_sendto sendto -#define prog_close close -#define prog_getuid getuid -#define prog_setuid setuid -#endif - -#endif /* _PROG_OPS_H_ */ diff --git a/sbin/ping6/Makefile b/sbin/ping6/Makefile deleted file mode 100644 index 6d3e93c0a..000000000 --- a/sbin/ping6/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -# $NetBSD: Makefile,v 1.16 2015/09/09 10:06:05 ozaki-r Exp $ - -.include - -USE_FORT?= yes # setuid -RUMPPRG= ping6 -MAN= ping6.8 - -BINOWN= root -BINMODE= 4555 - -CPPFLAGS+= -DINET6 -.if !defined(__MINIX) -CPPFLAGS+= -DIPSEC -.endif # !defined(__MINIX) - -.if !defined(__MINIX) -LDADD+= -lipsec -lm -DPADD+= ${LIBIPSEC} ${LIBM} -.else -LDADD+= -lm -DPADD+= ${LIBM} -.endif # defined(__MINIX) - -.PATH: ${.CURDIR}/../../lib/libc/net -RUMPSRCS= getaddrinfo.c getifaddrs.c getnameinfo.c -RUMPSRCS+= if_indextoname.c if_nametoindex.c -.if (${MKRUMP} != "no") -CPPFLAGS+= -DRUMP_ACTION -.endif - -.include diff --git a/sbin/ping6/ping6.8 b/sbin/ping6/ping6.8 deleted file mode 100644 index 544b0e0e0..000000000 --- a/sbin/ping6/ping6.8 +++ /dev/null @@ -1,449 +0,0 @@ -.\" $NetBSD: ping6.8,v 1.30 2015/05/15 08:02:39 kefren Exp $ -.\" $KAME: ping6.8,v 1.57 2002/05/26 13:18:25 itojun Exp $ -.\" -.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the project nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.Dd April 23, 2015 -.Dt PING6 8 -.Os -.Sh NAME -.Nm ping6 -.Nd send -.Tn ICMPv6 ECHO_REQUEST -packets to network hosts -.Sh SYNOPSIS -.Nm ping6 -.\" without IPsec, or new IPsec -.Op Fl dfHmnNoqRtvwW -.\" old IPsec -.\" .Op Fl AdEfnNqRtvwW -.Op Fl a Ar addrtype -.Op Fl b Ar bufsiz -.Op Fl c Ar count -.Op Fl g Ar gateway -.Op Fl h Ar hoplimit -.Op Fl I Ar interface -.Op Fl i Ar wait -.Op Fl l Ar preload -.Op Fl p Ar pattern -.\" new IPsec -.Op Fl P Ar policy -.Op Fl S Ar sourceaddr -.Op Fl s Ar packetsize -.Op Fl x Ar maxwait -.Op Fl X Ar deadline -.Op Ar hops ... -.Ar host -.Sh DESCRIPTION -.Nm -uses the -.Tn ICMPv6 -protocol's mandatory -.Tn ICMP6_ECHO_REQUEST -datagram to elicit an -.Tn ICMP6_ECHO_REPLY -from a host or gateway. -.Tn ICMP6_ECHO_REQUEST -datagrams (``pings'') have an IPv6 header, -and -.Tn ICMPv6 -header formatted as documented in RFC 2463. -The options are as follows: -.Bl -tag -width Ds -.\" old IPsec -.\" .It Fl A -.\" Enables transport-mode IPsec authentication header -.\" .Pq experimental . -.It Fl a Ar addrtype -Generate ICMPv6 Node Information Node Addresses query, rather than echo-request. -.Ar addrtype -must be a string constructed of the following characters. -.Bl -tag -width Ds -compact -.It Ic a -requests unicast addresses from all of the responder's interfaces. -If the character is omitted, -only those addresses which belong to the interface which has the -responder's address are requests. -.It Ic c -requests responder's IPv4-compatible and IPv4-mapped addresses. -.It Ic g -requests responder's global-scope addresses. -.It Ic s -requests responder's site-local addresses. -.It Ic l -requests responder's link-local addresses. -.It Ic A -requests responder's anycast addresses. -Without this character, the responder will return unicast addresses only. -With this character, the responder will return anycast addresses only. -Note that the specification does not specify how to get responder's -anycast addresses. -This is an experimental option. -.El -.It Fl b Ar bufsiz -Set socket buffer size. -.It Fl c Ar count -Stop after sending -.Pq and receiving -.Ar count -.Tn ECHO_RESPONSE -packets. -.It Fl d -Set the -.Dv SO_DEBUG -option on the socket being used. -.\" .It Fl E -.\" Enables transport-mode IPsec encapsulated security payload -.\" .Pq experimental . -.It Fl f -Flood ping. -Outputs packets as fast as they come back or one hundred times per second, -whichever is more. -For every -.Tn ECHO_REQUEST -sent a period -.Dq \&. -is printed, while for every -.Tn ECHO_REPLY -received a backspace is printed. -This provides a rapid display of how many packets are being dropped. -Only the super-user may use this option. -.Bf -emphasis -This can be very hard on a network and should be used with caution. -.Ef -.It Fl g Ar gateway -Specifies to use -.Ar gateway -as the next hop to the destination. -The gateway must be a neighbor of the sending node. -.It Fl H -Specifies to try reverse-lookup of IPv6 addresses. -The -.Nm -command does not try reverse-lookup unless the option is specified. -.It Fl h Ar hoplimit -Set the IPv6 hoplimit. -.It Fl I Ar interface -Source packets with the given interface address. -This flag applies if the ping destination is a multicast address, -or link-local/site-local unicast address. -.It Fl i Ar wait -Wait -.Ar wait -seconds -.Em between sending each packet . -The default is to wait for one second between each packet. -This option is incompatible with the -.Fl f -option. -.It Fl l Ar preload -If -.Ar preload -is specified, -.Nm -sends that many packets as fast as possible before falling into its normal -mode of behavior. -Only the super-user may use this option. -.It Fl m -By default, -.Nm -asks the kernel to fragment packets to fit into the minimum IPv6 MTU. -.Fl m -will suppress the behavior in the following two levels: -when the option is specified once, the behavior will be disabled for -unicast packets. -When the option is specified more than once, it will be disabled for both -unicast and multicast packets. -.It Fl n -Numeric output only. -No attempt will be made to lookup symbolic names from addresses in the reply. -.It Fl N -Probe node information multicast group -.Pq Li ff02::2:xxxx:xxxx . -.Ar host -must be string hostname of the target -.Pq must not be a numeric IPv6 address . -Node information multicast group will be computed based on given -.Ar host , -and will be used as the final destination. -Since node information multicast group is a link-local multicast group, -outgoing interface needs to be specified by -.Fl I -option. -.It Fl o -Exit successfully after receiving one reply packet. -.It Fl p Ar pattern -You may specify up to 16 -.Dq pad -bytes to fill out the packet you send. -This is useful for diagnosing data-dependent problems in a network. -For example, -.Dq Li \-p ff -will cause the sent packet to be filled with all -ones. -.\" new IPsec -.It Fl P Ar policy -.Ar policy -specifies IPsec policy to be used for the probe. -.It Fl q -Quiet output. -Nothing is displayed except the summary lines at startup time and -when finished. -.It Fl R -Make the kernel believe that the target -.Ar host -.Po -or the first -.Ar hop -if you specify -.Ar hops -.Pc -is reachable, by injecting upper-layer reachability confirmation hint. -The option is meaningful only if the target -.Ar host -.Pq or the first hop -is a neighbor. -.It Fl S Ar sourceaddr -Specifies the source address of request packets. -The source address must be one of the unicast addresses of the sending node, -and must be numeric. -.It Fl s Ar packetsize -Specifies the number of data bytes to be sent. -The default is 56, which translates into 64 -.Tn ICMP -data bytes when combined -with the 8 bytes of -.Tn ICMP -header data. -You may need to specify -.Fl b -as well to extend socket buffer size. -.It Fl t -Generate ICMPv6 Node Information supported query types query, -rather than echo-request. -.Fl s -has no effect if -.Fl t -is specified. -.It Fl v -Verbose output. -.Tn ICMP -packets other than -.Tn ECHO_RESPONSE -that are received are listed. -.It Fl w -Generate ICMPv6 Node Information DNS Name query, rather than echo-request. -.Fl s -has no effect if -.Fl w -is specified. -.It Fl W -Same as -.Fl w , -but with old packet format based on 03 draft. -This option is present for backward compatibility. -.Fl s -has no effect if -.Fl w -is specified. -.It Fl x Ar maxwait -Time in milliseconds to wait for a reply for each packet sent. -.It Fl X Ar deadline -Specify a timeout, in seconds, before ping exits regardless of -how many packets have been received. -.It Ar hops -IPv6 addresses for intermediate nodes, -which will be put into type 0 routing header. -.It Ar host -IPv6 address of the final destination node. -.El -.Pp -When using -.Nm -for fault isolation, it should first be run on the local host, to verify -that the local network interface is up and running. -Then, hosts and gateways further and further away should be -.Dq pinged . -Round-trip times and packet loss statistics are computed. -If duplicate packets are received, they are not included in the packet -loss calculation, although the round trip time of these packets is used -in calculating the round-trip time statistics. -When the specified number of packets have been sent -.Pq and received -or if the program is terminated with a -.Dv SIGINT , -a brief summary is displayed, showing the number of packets sent and -received, and the minimum, maximum, mean, and standard deviation of -the round-trip times. -.Pp -This program is intended for use in network testing, measurement and -management. -Because of the load it can impose on the network, it is unwise to use -.Nm -during normal operations or from automated scripts. -.\" .Sh ICMP PACKET DETAILS -.\" An IP header without options is 20 bytes. -.\" An -.\" .Tn ICMP -.\" .Tn ECHO_REQUEST -.\" packet contains an additional 8 bytes worth of -.\" .Tn ICMP -.\" header followed by an arbitrary amount of data. -.\" When a -.\" .Ar packetsize -.\" is given, this indicated the size of this extra piece of data -.\" .Pq the default is 56 . -.\" Thus the amount of data received inside of an IP packet of type -.\" .Tn ICMP -.\" .Tn ECHO_REPLY -.\" will always be 8 bytes more than the requested data space -.\" .Pq the Tn ICMP header . -.\" .Pp -.\" If the data space is at least eight bytes large, -.\" .Nm -.\" uses the first eight bytes of this space to include a timestamp which -.\" it uses in the computation of round trip times. -.\" If less than eight bytes of pad are specified, no round trip times are -.\" given. -.Sh DUPLICATE AND DAMAGED PACKETS -.Nm -will report duplicate and damaged packets. -Duplicate packets should never occur when pinging a unicast address, -and seem to be caused by -inappropriate link-level retransmissions. -Duplicates may occur in many situations and are rarely -.Pq if ever -a good sign, although the presence of low levels of duplicates may not -always be cause for alarm. -Duplicates are expected when pinging a multicast address, -since they are not really duplicates but replies from different hosts -to the same request. -.Pp -Damaged packets are obviously serious cause for alarm and often -indicate broken hardware somewhere in the -.Nm -packet's path -.Pq in the network or in the hosts . -.Sh TRYING DIFFERENT DATA PATTERNS -The -(inter)network -layer should never treat packets differently depending on the data -contained in the data portion. -Unfortunately, data-dependent problems have been known to sneak into -networks and remain undetected for long periods of time. -In many cases the particular pattern that will have problems is something -that does not have sufficient -.Dq transitions , -such as all ones or all zeros, or a pattern right at the edge, such as -almost all zeros. -It is not -necessarily enough to specify a data pattern of all zeros (for example) -on the command line because the pattern that is of interest is -at the data link level, and the relationship between what you type and -what the controllers transmit can be complicated. -.Pp -This means that if you have a data-dependent problem you will probably -have to do a lot of testing to find it. -If you are lucky, you may manage to find a file that either -cannot -be sent across your network or that takes much longer to transfer than -other similar length files. -You can then examine this file for repeated patterns that you can test -using the -.Fl p -option of -.Nm Ns . -.Sh EXIT STATUS -.Nm -exits with 0 on success (the host is alive), -and non-zero if the arguments are incorrect or the host is not responding. -.Sh EXAMPLES -Normally, -.Nm -works just like -.Xr ping 8 -would work; the following will send ICMPv6 echo request to -.Li dst.foo.com . -.Bd -literal -offset indent -ping6 -n dst.foo.com -.Ed -.Pp -The following will probe hostnames for all nodes on the network link attached to -.Li wi0 -interface. -The address -.Li ff02::1 -is named the link-local all-node multicast address, and the packet would -reach every node on the network link. -.Bd -literal -offset indent -ping6 -w ff02::1%wi0 -.Ed -.Pp -The following will probe addresses assigned to the destination node, -.Li dst.foo.com . -.Bd -literal -offset indent -ping6 -a agl dst.foo.com -.Ed -.Sh SEE ALSO -.Xr netstat 1 , -.Xr icmp6 4 , -.Xr inet6 4 , -.Xr ip6 4 , -.Xr ifconfig 8 , -.Xr ping 8 , -.Xr routed 8 , -.Xr traceroute 8 , -.Xr traceroute6 8 -.Rs -.%A A. Conta -.%A S. Deering -.%T "Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification" -.%N RFC 2463 -.%D December 1998 -.Re -.Rs -.%A Matt Crawford -.%T "IPv6 Node Information Queries" -.%N draft-ietf-ipngwg-icmp-name-lookups-09.txt -.%D May 2002 -.%O work in progress material -.Re -.Sh HISTORY -The -.Xr ping 8 -command appeared in -.Bx 4.3 . -The -.Nm -command with IPv6 support first appeared in the WIDE Hydrangea IPv6 -protocol stack kit. -.Sh BUGS -.\" except for bsdi -.Nm -is intentionally separate from -.Xr ping 8 . diff --git a/sbin/ping6/ping6_hostops.c b/sbin/ping6/ping6_hostops.c deleted file mode 100644 index 4c1d1c25e..000000000 --- a/sbin/ping6/ping6_hostops.c +++ /dev/null @@ -1,55 +0,0 @@ -/* $NetBSD: ping6_hostops.c,v 1.1 2015/08/06 14:45:54 ozaki-r Exp $ */ - -/* - * Copyright (c) 2015 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifndef lint -__RCSID("$NetBSD: ping6_hostops.c,v 1.1 2015/08/06 14:45:54 ozaki-r Exp $"); -#endif /* !lint */ - -#include -#include -#include - -#include -#include - -#include "prog_ops.h" - -const struct prog_ops prog_ops = { - .op_socket = socket, - .op_setsockopt = setsockopt, - .op_getsockname = getsockname, - .op_poll = poll, - .op_recvmsg = recvmsg, - .op_sendmsg = sendmsg, - .op_connect = connect, - .op_close = close, - .op_getuid = getuid, - .op_setuid = setuid, - .op_seteuid = seteuid, -}; diff --git a/sbin/ping6/ping6_rumpops.c b/sbin/ping6/ping6_rumpops.c deleted file mode 100644 index 672135aef..000000000 --- a/sbin/ping6/ping6_rumpops.c +++ /dev/null @@ -1,60 +0,0 @@ -/* $NetBSD: ping6_rumpops.c,v 1.1 2015/08/06 14:45:54 ozaki-r Exp $ */ - -/* - * Copyright (c) 2015 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifndef lint -__RCSID("$NetBSD: ping6_rumpops.c,v 1.1 2015/08/06 14:45:54 ozaki-r Exp $"); -#endif /* !lint */ - -#include -#include - -#include -#include - -#include -#include -#include - -#include "prog_ops.h" - -const struct prog_ops prog_ops = { - .op_init = rumpclient_init, - - .op_socket = rump_sys_socket, - .op_setsockopt= rump_sys_setsockopt, - .op_getsockname=rump_sys_getsockname, - .op_poll = rump_sys_poll, - .op_sendmsg = rump_sys_sendmsg, - .op_recvmsg = rump_sys_recvmsg, - .op_connect = rump_sys_connect, - .op_close = rump_sys_close, - .op_getuid = rump_sys_getuid, - .op_setuid = rump_sys_setuid, - .op_seteuid = rump_sys_seteuid, -}; diff --git a/sbin/ping6/prog_ops.h b/sbin/ping6/prog_ops.h deleted file mode 100644 index 144e9d10b..000000000 --- a/sbin/ping6/prog_ops.h +++ /dev/null @@ -1,86 +0,0 @@ -/* $NetBSD: prog_ops.h,v 1.1 2015/08/06 14:45:54 ozaki-r Exp $ */ - -/* - * Copyright (c) 2015 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _PROG_OPS_H_ -#define _PROG_OPS_H_ - -#include - -#ifndef CRUNCHOPS -struct prog_ops { - int (*op_init)(void); - - int (*op_socket)(int, int, int); - int (*op_setsockopt)(int, int, int, const void *, socklen_t); - int (*op_getsockname)(int, struct sockaddr * restrict, - socklen_t * restrict); - - int (*op_poll)(struct pollfd *, nfds_t, int); - - ssize_t (*op_recvmsg)(int, struct msghdr *, int); - ssize_t (*op_sendmsg)(int, const struct msghdr *, int); - - int (*op_connect)(int, const struct sockaddr *, socklen_t); - int (*op_close)(int); - - uid_t (*op_getuid)(void); - int (*op_setuid)(uid_t); - int (*op_seteuid)(uid_t); -}; -extern const struct prog_ops prog_ops; - -#define prog_init prog_ops.op_init -#define prog_socket prog_ops.op_socket -#define prog_setsockopt prog_ops.op_setsockopt -#define prog_getsockname prog_ops.op_getsockname -#define prog_shutdown prog_ops.op_shutdown -#define prog_poll prog_ops.op_poll -#define prog_recvmsg prog_ops.op_recvmsg -#define prog_sendmsg prog_ops.op_sendmsg -#define prog_connect prog_ops.op_connect -#define prog_close prog_ops.op_close -#define prog_getuid prog_ops.op_getuid -#define prog_setuid prog_ops.op_setuid -#define prog_seteuid prog_ops.op_seteuid -#else -#define prog_init ((int (*)(void))NULL) -#define prog_socket socket -#define prog_setsockopt setsockopt -#define prog_getsockname getsockname -#define prog_shutdown shutdown -#define prog_poll poll -#define prog_recvmsg recvmsg -#define prog_sendmsg sendmsg -#define prog_connect connect -#define prog_close close -#define prog_getuid getuid -#define prog_setuid setuid -#define prog_seteuid seteuid -#endif - -#endif /* _PROG_OPS_H_ */ diff --git a/sbin/rcorder/Makefile b/sbin/rcorder/Makefile deleted file mode 100644 index 86bd72e65..000000000 --- a/sbin/rcorder/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# $NetBSD: Makefile,v 1.8 2008/08/03 07:50:54 lukem Exp $ - -PROG= rcorder -SRCS= hash.c rcorder.c -MAN= rcorder.8 - -LDADD+=-lutil -DPADD+=${LIBUTIL} - -.include diff --git a/sbin/rcorder/hash.c b/sbin/rcorder/hash.c deleted file mode 100644 index caebde1af..000000000 --- a/sbin/rcorder/hash.c +++ /dev/null @@ -1,468 +0,0 @@ -/* $NetBSD: hash.c,v 1.5 2007/03/03 00:09:30 simonb Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: hash.c,v 1.5 2007/03/03 00:09:30 simonb Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)hash.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: hash.c,v 1.5 2007/03/03 00:09:30 simonb Exp $"); -#endif -#endif /* not lint */ -#endif - -#include - -#include -#include -#include -#include -#include - -/* hash.c -- - * - * This module contains routines to manipulate a hash table. - * See hash.h for a definition of the structure of the hash - * table. Hash tables grow automatically as the amount of - * information increases. - */ -#include "hash.h" - -/* - * Forward references to local procedures that are used before they're - * defined: - */ - -static void RebuildTable(Hash_Table *); - -/* - * The following defines the ratio of # entries to # buckets - * at which we rebuild the table to make it larger. - */ - -#define rebuildLimit 8 - -/* - *--------------------------------------------------------- - * - * Hash_InitTable -- - * - * This routine just sets up the hash table. - * - * Input: - * t Structure to use to hold table. - * numBuckets How many buckets to create for starters. This number - * is rounded up to a power of two. If <= 0, a reasonable - * default is chosen. The table will grow in size later - * as needed. - * - * Results: - * None. - * - * Side Effects: - * Memory is allocated for the initial bucket area. - * - *--------------------------------------------------------- - */ - -void -Hash_InitTable(Hash_Table *t, int numBuckets) -{ - int i; - struct Hash_Entry **hp; - - /* - * Round up the size to a power of two. - */ - if (numBuckets <= 0) - i = 16; - else { - for (i = 2; i < numBuckets; i <<= 1) - continue; - } - t->numEntries = 0; - t->size = i; - t->mask = i - 1; - t->bucketPtr = hp = (struct Hash_Entry **)emalloc(sizeof(*hp) * i); - while (--i >= 0) - *hp++ = NULL; -} - -/* - *--------------------------------------------------------- - * - * Hash_DeleteTable -- - * - * This routine removes everything from a hash table - * and frees up the memory space it occupied (except for - * the space in the Hash_Table structure). - * - * Results: - * None. - * - * Side Effects: - * Lots of memory is freed up. - * - *--------------------------------------------------------- - */ - -void -Hash_DeleteTable(Hash_Table *t) -{ - struct Hash_Entry **hp, *h, *nexth; - int i; - - nexth = NULL; - for (hp = t->bucketPtr, i = t->size; --i >= 0;) { - for (h = *hp++; h != NULL; h = nexth) { - nexth = h->next; - free(h); - } - } - free(t->bucketPtr); - - /* - * Set up the hash table to cause memory faults on any future access - * attempts until re-initialization. - */ - t->bucketPtr = NULL; -} - -/* - *--------------------------------------------------------- - * - * Hash_FindEntry -- - * - * Searches a hash table for an entry corresponding to key. - * - * Input: - * t Hash table to search. - * key A hash key. - * - * Results: - * The return value is a pointer to the entry for key, - * if key was present in the table. If key was not - * present, NULL is returned. - * - * Side Effects: - * None. - * - *--------------------------------------------------------- - */ - -Hash_Entry * -Hash_FindEntry(Hash_Table *t, char *key) -{ - Hash_Entry *e; - unsigned h; - char *p; - - for (h = 0, p = key; *p;) - h = (h << 5) - h + *p++; - p = key; - for (e = t->bucketPtr[h & t->mask]; e != NULL; e = e->next) - if (e->namehash == h && strcmp(e->name, p) == 0) - return (e); - return (NULL); -} - -/* - *--------------------------------------------------------- - * - * Hash_CreateEntry -- - * - * Searches a hash table for an entry corresponding to - * key. If no entry is found, then one is created. - * - * Input: - * t Hash table to search. - * key A hash key. - * newPtr Filled in with 1 if new entry created, 0 otherwise. - * - * Results: - * The return value is a pointer to the entry. If *newPtr - * isn't NULL, then *newPtr is filled in with TRUE if a - * new entry was created, and FALSE if an entry already existed - * with the given key. - * - * Side Effects: - * Memory may be allocated, and the hash buckets may be modified. - *--------------------------------------------------------- - */ - -Hash_Entry * -Hash_CreateEntry(Hash_Table *t, char *key, int *newPtr) -{ - Hash_Entry *e; - unsigned h; - char *p; - int keylen; - struct Hash_Entry **hp; - - /* - * Hash the key. As a side effect, save the length (strlen) of the - * key in case we need to create the entry. - */ - for (h = 0, p = key; *p;) - h = (h << 5) - h + *p++; - keylen = p - key; - p = key; - for (e = t->bucketPtr[h & t->mask]; e != NULL; e = e->next) { - if (e->namehash == h && strcmp(e->name, p) == 0) { - if (newPtr != NULL) - *newPtr = 0; - return (e); - } - } - - /* - * The desired entry isn't there. Before allocating a new entry, - * expand the table if necessary (and this changes the resulting - * bucket chain). - */ - if (t->numEntries >= rebuildLimit * t->size) - RebuildTable(t); - e = (Hash_Entry *) emalloc(sizeof(*e) + keylen); - hp = &t->bucketPtr[h & t->mask]; - e->next = *hp; - *hp = e; - e->clientData = NULL; - e->namehash = h; - (void) strcpy(e->name, p); - t->numEntries++; - - if (newPtr != NULL) - *newPtr = 1; - return (e); -} - -/* - *--------------------------------------------------------- - * - * Hash_DeleteEntry -- - * - * Delete the given hash table entry and free memory associated with - * it. - * - * Results: - * None. - * - * Side Effects: - * Hash chain that entry lives in is modified and memory is freed. - * - *--------------------------------------------------------- - */ - -void -Hash_DeleteEntry(Hash_Table *t, Hash_Entry *e) -{ - Hash_Entry **hp, *p; - - if (e == NULL) - return; - for (hp = &t->bucketPtr[e->namehash & t->mask]; - (p = *hp) != NULL; hp = &p->next) { - if (p == e) { - *hp = p->next; - free(p); - t->numEntries--; - return; - } - } - (void)write(2, "bad call to Hash_DeleteEntry\n", 29); - abort(); -} - -/* - *--------------------------------------------------------- - * - * Hash_EnumFirst -- - * This procedure sets things up for a complete search - * of all entries recorded in the hash table. - * - * Input: - * t Table to be searched. - * searchPtr Area in which to keep state about search. - * - * Results: - * The return value is the address of the first entry in - * the hash table, or NULL if the table is empty. - * - * Side Effects: - * The information in searchPtr is initialized so that successive - * calls to Hash_Next will return successive HashEntry's - * from the table. - * - *--------------------------------------------------------- - */ - -Hash_Entry * -Hash_EnumFirst(Hash_Table *t, Hash_Search *searchPtr) -{ - - searchPtr->tablePtr = t; - searchPtr->nextIndex = 0; - searchPtr->hashEntryPtr = NULL; - return Hash_EnumNext(searchPtr); -} - -/* - *--------------------------------------------------------- - * - * Hash_EnumNext -- - * This procedure returns successive entries in the hash table. - * - * Results: - * The return value is a pointer to the next HashEntry - * in the table, or NULL when the end of the table is - * reached. - * - * Side Effects: - * The information in searchPtr is modified to advance to the - * next entry. - * - *--------------------------------------------------------- - */ - -Hash_Entry * -Hash_EnumNext(Hash_Search *searchPtr) -{ - Hash_Entry *e; - Hash_Table *t = searchPtr->tablePtr; - - /* - * The hashEntryPtr field points to the most recently returned - * entry, or is nil if we are starting up. If not nil, we have - * to start at the next one in the chain. - */ - e = searchPtr->hashEntryPtr; - if (e != NULL) - e = e->next; - /* - * If the chain ran out, or if we are starting up, we need to - * find the next nonempty chain. - */ - while (e == NULL) { - if (searchPtr->nextIndex >= t->size) - return (NULL); - e = t->bucketPtr[searchPtr->nextIndex++]; - } - searchPtr->hashEntryPtr = e; - return (e); -} - -/* - *--------------------------------------------------------- - * - * RebuildTable -- - * This local routine makes a new hash table that - * is larger than the old one. - * - * Results: - * None. - * - * Side Effects: - * The entire hash table is moved, so any bucket numbers - * from the old table are invalid. - * - *--------------------------------------------------------- - */ - -static void -RebuildTable(Hash_Table *t) -{ - Hash_Entry *e, *next, **hp, **xp; - int i, mask; - Hash_Entry **oldhp; - int oldsize; - - next = NULL; - oldhp = t->bucketPtr; - oldsize = i = t->size; - i <<= 1; - t->size = i; - t->mask = mask = i - 1; - t->bucketPtr = hp = (struct Hash_Entry **) emalloc(sizeof(*hp) * i); - while (--i >= 0) - *hp++ = NULL; - for (hp = oldhp, i = oldsize; --i >= 0;) { - for (e = *hp++; e != NULL; e = next) { - next = e->next; - xp = &t->bucketPtr[e->namehash & mask]; - e->next = *xp; - *xp = e; - } - } - free(oldhp); -} diff --git a/sbin/rcorder/hash.h b/sbin/rcorder/hash.h deleted file mode 100644 index 60c79e847..000000000 --- a/sbin/rcorder/hash.h +++ /dev/null @@ -1,161 +0,0 @@ -/* $NetBSD: hash.h,v 1.3 2003/08/07 10:04:37 agc Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)hash.h 8.1 (Berkeley) 6/6/93 - */ - -/* - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)hash.h 8.1 (Berkeley) 6/6/93 - */ - -/* hash.h -- - * - * This file contains definitions used by the hash module, - * which maintains hash tables. - */ - -#ifndef _HASH -#define _HASH - -/* - * The following defines one entry in the hash table. - */ - -typedef struct Hash_Entry { - struct Hash_Entry *next; /* Used to link together all the - * entries associated with the same - * bucket. */ - void *clientData; /* Arbitrary piece of data associated - * with key. */ - unsigned namehash; /* hash value of key */ - char name[1]; /* key string */ -} Hash_Entry; - -typedef struct Hash_Table { - struct Hash_Entry **bucketPtr; - /* Pointers to Hash_Entry, one - * for each bucket in the table. */ - int size; /* Actual size of array. */ - int numEntries; /* Number of entries in the table. */ - int mask; /* Used to select bits for hashing. */ -} Hash_Table; - -/* - * The following structure is used by the searching routines - * to record where we are in the search. - */ - -typedef struct Hash_Search { - Hash_Table *tablePtr; /* Table being searched. */ - int nextIndex; /* Next bucket to check (after - * current). */ - Hash_Entry *hashEntryPtr; /* Next entry to check in current - * bucket. */ -} Hash_Search; - -/* - * Macros. - */ - -/* - * void *Hash_GetValue(h) - * Hash_Entry *h; - */ - -#define Hash_GetValue(h) ((h)->clientData) - -/* - * Hash_SetValue(h, val); - * Hash_Entry *h; - * char *val; - */ - -#define Hash_SetValue(h, val) ((h)->clientData = (void *) (val)) - -/* - * Hash_GetKey(h); - * Hash_Entry *h; - */ - -#define Hash_GetKey(h) ((h)->name) - -/* - * Hash_Size(n) returns the number of words in an object of n bytes - */ - -#define Hash_Size(n) (((n) + sizeof (int) - 1) / sizeof (int)) - -void Hash_InitTable(Hash_Table *, int); -void Hash_DeleteTable(Hash_Table *); -Hash_Entry *Hash_FindEntry(Hash_Table *, char *); -Hash_Entry *Hash_CreateEntry(Hash_Table *, char *, int *); -void Hash_DeleteEntry(Hash_Table *, Hash_Entry *); -Hash_Entry *Hash_EnumFirst(Hash_Table *, Hash_Search *); -Hash_Entry *Hash_EnumNext(Hash_Search *); - -#endif /* _HASH */ diff --git a/sbin/rcorder/rcorder-visualize.sh b/sbin/rcorder/rcorder-visualize.sh deleted file mode 100644 index 763b5abc6..000000000 --- a/sbin/rcorder/rcorder-visualize.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh -# $NetBSD: rcorder-visualize.sh,v 1.5 2009/08/09 17:08:53 apb Exp $ -# -# Written by Joerg Sonnenberger. You may freely use and redistribute -# this script. -# -# Simple script to show the dependency graph for rc scripts. -# Output is in the dot(1) language and can be rendered using -# sh rcorder-visualize | dot -T svg -o rcorder.svg -# dot(1) can be found in graphics/graphviz in pkgsrc. - -rc_files=${*:-/etc/rc.d/*} - -{ -echo ' digraph {' -for f in $rc_files; do -< $f awk ' -/# PROVIDE: / { provide = $3 } -/# REQUIRE: / { for (i = 3; i <= NF; i++) requires[$i] = $i } -/# BEFORE: / { for (i = 3; i <= NF; i++) befores[$i] = $i } - -END { - print " \"" provide "\";" - for (x in requires) print " \"" provide "\"->\"" x "\";" - for (x in befores) print " \"" x "\"->\"" provide "\";" -} -' -done -echo '}' -} diff --git a/sbin/rcorder/rcorder.8 b/sbin/rcorder/rcorder.8 deleted file mode 100644 index 855eabc19..000000000 --- a/sbin/rcorder/rcorder.8 +++ /dev/null @@ -1,171 +0,0 @@ -.\" $NetBSD: rcorder.8,v 1.10 2014/03/18 18:20:39 riastradh Exp $ -.\" -.\" Copyright (c) 1998 -.\" Perry E. Metzger. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgment: -.\" This product includes software developed for the NetBSD Project -.\" by Perry E. Metzger. -.\" 4. The name of the author may not be used to endorse or promote products -.\" derived from this software without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.\" -.Dd April 23, 2003 -.Dt RCORDER 8 -.Os -.Sh NAME -.Nm rcorder -.Nd print a dependency ordering of interdependent files -.Sh SYNOPSIS -.Nm -.Op Fl k Ar keep -.Op Fl s Ar skip -.Ar -.Sh DESCRIPTION -.Nm -is designed to print out a dependency ordering of a set of -interdependent files. -Typically it is used to find an execution sequence for a set of -shell scripts in which certain files must be executed before others. -.Pp -Each file passed to -.Nm -should be annotated with special lines (which look like comments to the -shell) which indicate the dependencies the files have upon certain -points in the sequence, known as -.Dq conditions , -and which indicate, for each file, which -.Dq conditions -may be expected to be filled by that file. -.Pp -Within each file, a block containing a series of -.Dq REQUIRE , -.Dq PROVIDE , -.Dq BEFORE -and -.Dq KEYWORD -lines should appear. -The format of the lines is rigid. -Each line must begin with a single -.Dq # , -followed by a single space, followed by -.Dq PROVIDE: , -.Dq REQUIRE: , -.Dq BEFORE: , -or -.Dq KEYWORD: . -No deviation is permitted. -Each dependency line is then followed by a series of conditions, -separated by whitespace. -Multiple -.Dq PROVIDE , -.Dq REQUIRE , -.Dq BEFORE -and -.Dq KEYWORD -lines may appear, but all such lines must appear in a sequence without -any intervening lines, as once a line that does not follow the format -is reached, parsing stops. -.Pp -The options are as follows: -.Bl -tag -width Ds -.It Fl k -Add the specified keyword to the -.Dq keep list . -If any -.Fl k -option is given, only those files containing the matching keyword are listed. -.It Fl s -Add the specified keyword to the -.Dq skip list . -If any -.Fl s -option is given, files containing the matching keyword are not listed. -.El -.Pp - An example block follows: -.Bd -literal -offset indent -# REQUIRE: networking syslog -# REQUIRE: usr -# PROVIDE: dns nscd -.Ed -.Pp -This block states that the file in which it appears depends upon the -.Dq networking , -.Dq syslog , -and -.Dq usr -conditions, and provides the -.Dq dns -and -.Dq nscd -conditions. -.Pp -A file may contain zero -.Dq PROVIDE -lines, in which case it provides no conditions, and may contain zero -.Dq REQUIRE -lines, in which case it has no dependencies. -A file containing no -.Dq PROVIDE , -.Dq REQUIRE , -or -.Dq BEFORE -lines may be output at an arbitrary position in the dependency -ordering. -.Pp -There must be at least one file with no dependencies in the set of -arguments passed to -.Nm -in order for it to find a starting place in the dependency ordering. -.Sh DIAGNOSTICS -.Nm -may print one of the following error messages and exit with a non-zero -status if it encounters an error while processing the file list. -.Bl -diag -.It "Requirement %s has no providers, aborting." -No file has a -.Dq PROVIDE -line corresponding to a condition present in a -.Dq REQUIRE -line in another file. -.It "Circular dependency on provision %s, aborting." -A set of files has a circular dependency which was detected while -processing the stated condition. -.It "Circular dependency on file %s, aborting." -A set of files has a circular dependency which was detected while -processing the stated file. -.El -.Sh SEE ALSO -.Xr rc 8 -.Sh HISTORY -The -.Nm -program first appeared in -.Nx 1.5 . -.Sh AUTHORS -.An -nosplit -Written by -.An Perry E. Metzger Aq Mt perry@piermont.com -and -.An Matthew R. Green Aq Mt mrg@eterna.com.au . diff --git a/sbin/rcorder/rcorder.c b/sbin/rcorder/rcorder.c deleted file mode 100644 index 7bd7c6e8e..000000000 --- a/sbin/rcorder/rcorder.c +++ /dev/null @@ -1,771 +0,0 @@ -/* $NetBSD: rcorder.c,v 1.18 2016/09/05 01:09:57 sevan Exp $ */ - -/* - * Copyright (c) 1998, 1999 Matthew R. Green - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Copyright (c) 1998 - * Perry E. Metzger. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed for the NetBSD Project - * by Perry E. Metzger. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "hash.h" - -#ifdef DEBUG -int debug = 0; -# define DPRINTF(args) if (debug) { fflush(stdout); fprintf args; } -#else -# define DPRINTF(args) -#endif - -#define REQUIRE_STR "# REQUIRE:" -#define REQUIRE_LEN (sizeof(REQUIRE_STR) - 1) -#define REQUIRES_STR "# REQUIRES:" -#define REQUIRES_LEN (sizeof(REQUIRES_STR) - 1) -#define PROVIDE_STR "# PROVIDE:" -#define PROVIDE_LEN (sizeof(PROVIDE_STR) - 1) -#define PROVIDES_STR "# PROVIDES:" -#define PROVIDES_LEN (sizeof(PROVIDES_STR) - 1) -#define BEFORE_STR "# BEFORE:" -#define BEFORE_LEN (sizeof(BEFORE_STR) - 1) -#define KEYWORD_STR "# KEYWORD:" -#define KEYWORD_LEN (sizeof(KEYWORD_STR) - 1) -#define KEYWORDS_STR "# KEYWORDS:" -#define KEYWORDS_LEN (sizeof(KEYWORDS_STR) - 1) - -int exit_code; -int file_count; -char **file_list; - -enum { - RESET = 0, - SET = 1, -}; - -Hash_Table provide_hash_s, *provide_hash; - -typedef struct provnode provnode; -typedef struct filenode filenode; -typedef struct f_provnode f_provnode; -typedef struct f_reqnode f_reqnode; -typedef struct strnodelist strnodelist; - -struct provnode { - int head; - int in_progress; - filenode *fnode; - provnode *next, *last; -}; - -struct f_provnode { - provnode *pnode; - f_provnode *next; -}; - -struct f_reqnode { - Hash_Entry *entry; - f_reqnode *next; -}; - -struct strnodelist { - filenode *node; - strnodelist *next; - char s[1]; -}; - -struct filenode { - char *filename; - int in_progress; - filenode *next, *last; - f_reqnode *req_list; - f_provnode *prov_list; - strnodelist *keyword_list; -}; - -filenode fn_head_s, *fn_head; - -strnodelist *bl_list; -strnodelist *keep_list; -strnodelist *skip_list; - -void do_file(filenode *fnode); -void strnode_add(strnodelist **, char *, filenode *); -int skip_ok(filenode *fnode); -int keep_ok(filenode *fnode); -void satisfy_req(f_reqnode *rnode, char *); -void crunch_file(char *); -void parse_line(filenode *, char *, void (*)(filenode *, char *)); -filenode *filenode_new(char *); -void add_require(filenode *, char *); -void add_provide(filenode *, char *); -void add_before(filenode *, char *); -void add_keyword(filenode *, char *); -void insert_before(void); -Hash_Entry *make_fake_provision(filenode *); -void crunch_all_files(void); -void initialize(void); -void generate_ordering(void); - -int -main(int argc, char *argv[]) -{ - int ch; - - while ((ch = getopt(argc, argv, "dk:s:")) != -1) - switch (ch) { - case 'd': -#ifdef DEBUG - debug = 1; -#else - warnx("debugging not compiled in, -d ignored"); -#endif - break; - case 'k': - strnode_add(&keep_list, optarg, 0); - break; - case 's': - strnode_add(&skip_list, optarg, 0); - break; - default: - /* XXX should crunch it? */ - break; - } - argc -= optind; - argv += optind; - - file_count = argc; - file_list = argv; - - DPRINTF((stderr, "parse_args\n")); - initialize(); - DPRINTF((stderr, "initialize\n")); - crunch_all_files(); - DPRINTF((stderr, "crunch_all_files\n")); - generate_ordering(); - DPRINTF((stderr, "generate_ordering\n")); - - exit(exit_code); -} - -/* - * initialise various variables. - */ -void -initialize(void) -{ - - fn_head = &fn_head_s; - - provide_hash = &provide_hash_s; - Hash_InitTable(provide_hash, file_count); -} - -/* generic function to insert a new strnodelist element */ -void -strnode_add(strnodelist **listp, char *s, filenode *fnode) -{ - strnodelist *ent; - - ent = emalloc(sizeof *ent + strlen(s)); - ent->node = fnode; - strcpy(ent->s, s); - ent->next = *listp; - *listp = ent; -} - -/* - * below are the functions that deal with creating the lists - * from the filename's given and the dependancies and provisions - * in each of these files. no ordering or checking is done here. - */ - -/* - * we have a new filename, create a new filenode structure. - * fill in the bits, and put it in the filenode linked list - */ -filenode * -filenode_new(char *filename) -{ - filenode *temp; - - temp = emalloc(sizeof(*temp)); - memset(temp, 0, sizeof(*temp)); - temp->filename = estrdup(filename); - temp->req_list = NULL; - temp->prov_list = NULL; - temp->keyword_list = NULL; - temp->in_progress = RESET; - /* - * link the filenode into the list of filenodes. - * note that the double linking means we can delete a - * filenode without searching for where it belongs. - */ - temp->next = fn_head->next; - if (temp->next != NULL) - temp->next->last = temp; - temp->last = fn_head; - fn_head->next = temp; - return (temp); -} - -/* - * add a requirement to a filenode. - */ -void -add_require(filenode *fnode, char *s) -{ - Hash_Entry *entry; - f_reqnode *rnode; - int new; - - entry = Hash_CreateEntry(provide_hash, s, &new); - if (new) - Hash_SetValue(entry, NULL); - rnode = emalloc(sizeof(*rnode)); - rnode->entry = entry; - rnode->next = fnode->req_list; - fnode->req_list = rnode; -} - -/* - * add a provision to a filenode. if this provision doesn't - * have a head node, create one here. - */ -void -add_provide(filenode *fnode, char *s) -{ - Hash_Entry *entry; - f_provnode *f_pnode; - provnode *pnode, *head; - int new; - - entry = Hash_CreateEntry(provide_hash, s, &new); - head = Hash_GetValue(entry); - - /* create a head node if necessary. */ - if (head == NULL) { - head = emalloc(sizeof(*head)); - head->head = SET; - head->in_progress = RESET; - head->fnode = NULL; - head->last = head->next = NULL; - Hash_SetValue(entry, head); - } -#if 0 - /* - * Don't warn about this. We want to be able to support - * scripts that do two complex things: - * - * - Two independent scripts which both provide the - * same thing. Both scripts must be executed in - * any order to meet the barrier. An example: - * - * Script 1: - * - * PROVIDE: mail - * REQUIRE: LOGIN - * - * Script 2: - * - * PROVIDE: mail - * REQUIRE: LOGIN - * - * - Two interdependent scripts which both provide the - * same thing. Both scripts must be executed in - * graph order to meet the barrier. An example: - * - * Script 1: - * - * PROVIDE: nameservice dnscache - * REQUIRE: SERVERS - * - * Script 2: - * - * PROVIDE: nameservice nscd - * REQUIRE: dnscache - */ - else if (new == 0) { - warnx("file `%s' provides `%s'.", fnode->filename, s); - warnx("\tpreviously seen in `%s'.", - head->next->fnode->filename); - } -#endif - - pnode = emalloc(sizeof(*pnode)); - pnode->head = RESET; - pnode->in_progress = RESET; - pnode->fnode = fnode; - pnode->next = head->next; - pnode->last = head; - head->next = pnode; - if (pnode->next != NULL) - pnode->next->last = pnode; - - f_pnode = emalloc(sizeof(*f_pnode)); - f_pnode->pnode = pnode; - f_pnode->next = fnode->prov_list; - fnode->prov_list = f_pnode; -} - -/* - * put the BEFORE: lines to a list and handle them later. - */ -void -add_before(filenode *fnode, char *s) -{ - - strnode_add(&bl_list, s, fnode); -} - -/* - * add a key to a filenode. - */ -void -add_keyword(filenode *fnode, char *s) -{ - - strnode_add(&fnode->keyword_list, s, fnode); -} - -/* - * loop over the rest of a line, giving each word to - * add_func() to do the real work. - */ -void -parse_line(filenode *node, char *buffer, void (*add_func)(filenode *, char *)) -{ - char *s; - - while ((s = strsep(&buffer, " \t\n")) != NULL) - if (*s != '\0') - (*add_func)(node, s); -} - -/* - * given a file name, create a filenode for it, read in lines looking - * for provision and requirement lines, building the graphs as needed. - */ -void -crunch_file(char *filename) -{ - FILE *fp; - char *buf; - int require_flag, provide_flag, before_flag, keyword_flag; - enum { BEFORE_PARSING, PARSING, PARSING_DONE } state; - filenode *node; - char delims[3] = { '\\', '\\', '\0' }; - struct stat st; - - if ((fp = fopen(filename, "r")) == NULL) { - warn("could not open %s", filename); - return; - } - - if (fstat(fileno(fp), &st) == -1) { - warn("could not stat %s", filename); - fclose(fp); - return; - } - - if (!S_ISREG(st.st_mode)) { -#if 0 - warnx("%s is not a file", filename); -#endif - fclose(fp); - return; - } - - node = filenode_new(filename); - - /* - * we don't care about length, line number, don't want # for comments, - * and have no flags. - */ - for (state = BEFORE_PARSING; state != PARSING_DONE && - (buf = fparseln(fp, NULL, NULL, delims, 0)) != NULL; free(buf)) { - require_flag = provide_flag = before_flag = keyword_flag = 0; - if (strncmp(REQUIRE_STR, buf, REQUIRE_LEN) == 0) - require_flag = REQUIRE_LEN; - else if (strncmp(REQUIRES_STR, buf, REQUIRES_LEN) == 0) - require_flag = REQUIRES_LEN; - else if (strncmp(PROVIDE_STR, buf, PROVIDE_LEN) == 0) - provide_flag = PROVIDE_LEN; - else if (strncmp(PROVIDES_STR, buf, PROVIDES_LEN) == 0) - provide_flag = PROVIDES_LEN; - else if (strncmp(BEFORE_STR, buf, BEFORE_LEN) == 0) - before_flag = BEFORE_LEN; - else if (strncmp(KEYWORD_STR, buf, KEYWORD_LEN) == 0) - keyword_flag = KEYWORD_LEN; - else if (strncmp(KEYWORDS_STR, buf, KEYWORDS_LEN) == 0) - keyword_flag = KEYWORDS_LEN; - else { - if (state == PARSING) - state = PARSING_DONE; - continue; - } - - state = PARSING; - if (require_flag) - parse_line(node, buf + require_flag, add_require); - else if (provide_flag) - parse_line(node, buf + provide_flag, add_provide); - else if (before_flag) - parse_line(node, buf + before_flag, add_before); - else if (keyword_flag) - parse_line(node, buf + keyword_flag, add_keyword); - } - fclose(fp); -} - -Hash_Entry * -make_fake_provision(filenode *node) -{ - Hash_Entry *entry; - f_provnode *f_pnode; - provnode *head, *pnode; - static int i = 0; - int new; - char buffer[30]; - - do { - snprintf(buffer, sizeof buffer, "fake_prov_%08d", i++); - entry = Hash_CreateEntry(provide_hash, buffer, &new); - } while (new == 0); - head = emalloc(sizeof(*head)); - head->head = SET; - head->in_progress = RESET; - head->fnode = NULL; - head->last = head->next = NULL; - Hash_SetValue(entry, head); - - pnode = emalloc(sizeof(*pnode)); - pnode->head = RESET; - pnode->in_progress = RESET; - pnode->fnode = node; - pnode->next = head->next; - pnode->last = head; - head->next = pnode; - if (pnode->next != NULL) - pnode->next->last = pnode; - - f_pnode = emalloc(sizeof(*f_pnode)); - f_pnode->pnode = pnode; - f_pnode->next = node->prov_list; - node->prov_list = f_pnode; - - return (entry); -} - -/* - * go through the BEFORE list, inserting requirements into the graph(s) - * as required. in the before list, for each entry B, we have a file F - * and a string S. we create a "fake" provision (P) that F provides. - * for each entry in the provision list for S, add a requirement to - * that provisions filenode for P. - */ -void -insert_before(void) -{ - Hash_Entry *entry, *fake_prov_entry; - provnode *pnode; - f_reqnode *rnode; - strnodelist *bl; - int new; - - while (bl_list != NULL) { - bl = bl_list->next; - - fake_prov_entry = make_fake_provision(bl_list->node); - - entry = Hash_CreateEntry(provide_hash, bl_list->s, &new); - if (new == 1) - warnx("file `%s' is before unknown provision `%s'", - bl_list->node->filename, bl_list->s); - - for (pnode = Hash_GetValue(entry); pnode; pnode = pnode->next) { - if (pnode->head) - continue; - - rnode = emalloc(sizeof(*rnode)); - rnode->entry = fake_prov_entry; - rnode->next = pnode->fnode->req_list; - pnode->fnode->req_list = rnode; - } - - free(bl_list); - bl_list = bl; - } -} - -/* - * loop over all the files calling crunch_file() on them to do the - * real work. after we have built all the nodes, insert the BEFORE: - * lines into graph(s). - */ -void -crunch_all_files(void) -{ - int i; - - for (i = 0; i < file_count; i++) - crunch_file(file_list[i]); - insert_before(); -} - -/* - * below are the functions that traverse the graphs we have built - * finding out the desired ordering, printing each file in turn. - * if missing requirements, or cyclic graphs are detected, a - * warning will be issued, and we will continue on.. - */ - -/* - * given a requirement node (in a filename) we attempt to satisfy it. - * we do some sanity checking first, to ensure that we have providers, - * aren't already satisfied and aren't already being satisfied (ie, - * cyclic). if we pass all this, we loop over the provision list - * calling do_file() (enter recursion) for each filenode in this - * provision. - */ -void -satisfy_req(f_reqnode *rnode, char *filename) -{ - Hash_Entry *entry; - provnode *head; - - entry = rnode->entry; - head = Hash_GetValue(entry); - - if (head == NULL) { - warnx("requirement `%s' in file `%s' has no providers.", - Hash_GetKey(entry), filename); - exit_code = 1; - return; - } - - /* return if the requirement is already satisfied. */ - if (head->next == NULL) - return; - - /* - * if list is marked as in progress, - * print that there is a circular dependency on it and abort - */ - if (head->in_progress == SET) { - warnx("Circular dependency on provision `%s' in file `%s'.", - Hash_GetKey(entry), filename); - exit_code = 1; - return; - } - - head->in_progress = SET; - - /* - * while provision_list is not empty - * do_file(first_member_of(provision_list)); - */ - while (head->next != NULL) - do_file(head->next->fnode); -} - -int -skip_ok(filenode *fnode) -{ - strnodelist *s; - strnodelist *k; - - for (s = skip_list; s; s = s->next) - for (k = fnode->keyword_list; k; k = k->next) - if (strcmp(k->s, s->s) == 0) - return (0); - - return (1); -} - -int -keep_ok(filenode *fnode) -{ - strnodelist *s; - strnodelist *k; - - for (s = keep_list; s; s = s->next) - for (k = fnode->keyword_list; k; k = k->next) - if (strcmp(k->s, s->s) == 0) - return (1); - - /* an empty keep_list means every one */ - return (!keep_list); -} - -/* - * given a filenode, we ensure we are not a cyclic graph. if this - * is ok, we loop over the filenodes requirements, calling satisfy_req() - * for each of them.. once we have done this, remove this filenode - * from each provision table, as we are now done. - * - * NOTE: do_file() is called recursively from several places and cannot - * safely free() anything related to items that may be recursed on. - * Circular dependancies will cause problems if we do. - */ -void -do_file(filenode *fnode) -{ - f_reqnode *r; - f_provnode *p, *p_tmp; - provnode *pnode; - int was_set; - - DPRINTF((stderr, "do_file on %s.\n", fnode->filename)); - - /* - * if fnode is marked as in progress, - * print that fnode; is circularly depended upon and abort. - */ - if (fnode->in_progress == SET) { - warnx("Circular dependency on file `%s'.", - fnode->filename); - was_set = exit_code = 1; - } else - was_set = 0; - - /* mark fnode */ - fnode->in_progress = SET; - - /* - * for each requirement of fnode -> r - * satisfy_req(r, filename) - */ - r = fnode->req_list; - while (r != NULL) { -#if 0 - f_reqnode *r_tmp = r; -#endif - satisfy_req(r, fnode->filename); - r = r->next; -#if 0 - free(r_tmp); -#endif - } - fnode->req_list = NULL; - - /* - * for each provision of fnode -> p - * remove fnode from provision list for p in hash table - */ - p = fnode->prov_list; - while (p != NULL) { - p_tmp = p; - pnode = p->pnode; - if (pnode->next != NULL) { - pnode->next->last = pnode->last; - } - if (pnode->last != NULL) { - pnode->last->next = pnode->next; - } - free(pnode); - p = p->next; - free(p_tmp); - } - fnode->prov_list = NULL; - - /* do_it(fnode) */ - DPRINTF((stderr, "next do: ")); - - /* if we were already in progress, don't print again */ - if (was_set == 0 && skip_ok(fnode) && keep_ok(fnode)) - printf("%s\n", fnode->filename); - - if (fnode->next != NULL) { - fnode->next->last = fnode->last; - } - if (fnode->last != NULL) { - fnode->last->next = fnode->next; - } - - DPRINTF((stderr, "nuking %s\n", fnode->filename)); -#if 0 - free(fnode->filename); - free(fnode); -#endif -} - -void -generate_ordering(void) -{ - - /* - * while there remain undone files{f}, - * pick an arbitrary f, and do_file(f) - * Note that the first file in the file list is perfectly - * arbitrary, and easy to find, so we use that. - */ - - /* - * N.B.: the file nodes "self delete" after they execute, so - * after each iteration of the loop, the head will be pointing - * to something totally different. The loop ends up being - * executed only once for every strongly connected set of - * nodes. - */ - while (fn_head->next != NULL) { - DPRINTF((stderr, "generate on %s\n", fn_head->next->filename)); - do_file(fn_head->next); - } -} diff --git a/sbin/shutdown/Makefile b/sbin/shutdown/Makefile deleted file mode 100644 index da2f31742..000000000 --- a/sbin/shutdown/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# $NetBSD: Makefile,v 1.11 2009/04/11 07:58:13 lukem Exp $ -# @(#)Makefile 8.1 (Berkeley) 6/5/93 - -USE_FORT?=yes # setuid -PROG= shutdown -MAN= shutdown.8 -BINOWN= root -BINGRP= operator -BINMODE=4554 - -.include diff --git a/sbin/shutdown/pathnames.h b/sbin/shutdown/pathnames.h deleted file mode 100644 index 42a33bd84..000000000 --- a/sbin/shutdown/pathnames.h +++ /dev/null @@ -1,45 +0,0 @@ -/* $NetBSD: pathnames.h,v 1.9 2004/08/19 22:30:10 christos Exp $ */ - -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)pathnames.h 8.1 (Berkeley) 6/5/93 - */ - -#include - -#define _PATH_FASTBOOT "/fastboot" -#ifdef RESCUEDIR -#define _PATH_HALT RESCUEDIR "/halt" -#define _PATH_REBOOT RESCUEDIR "/reboot" -#else -#define _PATH_HALT "/sbin/halt" -#define _PATH_REBOOT "/sbin/reboot" -#endif -#define _PATH_WALL "/usr/bin/wall" -#define _PATH_RCSHUTDOWN "/etc/rc.shutdown" diff --git a/sbin/shutdown/shutdown.8 b/sbin/shutdown/shutdown.8 deleted file mode 100644 index 9368dc921..000000000 --- a/sbin/shutdown/shutdown.8 +++ /dev/null @@ -1,245 +0,0 @@ -.\" $NetBSD: shutdown.8,v 1.33 2016/09/14 00:16:31 kre Exp $ -.\" -.\" Copyright (c) 1988, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)shutdown.8 8.2 (Berkeley) 4/27/95 -.\" -.Dd September 12, 2016 -.Dt SHUTDOWN 8 -.Os -.Sh NAME -.Nm shutdown -.Nd close down the system at a given time -.Sh SYNOPSIS -.Nm -.Op Fl Ddfhknprvxz -.Op Fl b Ar bootstr -.Ar time -.Op Ar message ... | Ar - -.Sh DESCRIPTION -.Nm -provides an automated shutdown procedure for super-users -to nicely notify users when the system is shutting down, -saving them from system administrators, hackers, and gurus, who -would otherwise not bother with such niceties. -.Pp -Available friendlinesses: -.Bl -tag -width bootstr -.It Fl b Ar bootstr -The given -.Ar bootstr -is passed to -.Xr reboot 8 -for the benefit of those systems that can pass boot arguments to the -firmware. -Currently, this only affects sun3 and sparc machines. -.It Fl d -.Nm -will pass the -.Fl d -flag to -.Xr reboot 8 -or -.Xr halt 8 -to request a kernel core dump. -If neither the -.Fl h -or -.Fl r -flags are specified, then -.Fl d -also implies -.Fl r . -.It Fl f -.Nm -arranges, in the manner of -.Xr fastboot 8 , -for the file systems -.Em not to be -checked on reboot. -.It Fl h -The system is halted at the specified -.Ar time , -using -.Xr halt 8 . -.It Fl k -Kick everybody off. -The -.Fl k -option -does not actually halt the system, but leaves the -system multi-user with logins disabled (for all but super-user). -.It Fl n -Prevent the normal -.Xr sync 2 -before stopping. -.It Fl p -The system is powered down at the specified -.Ar time , -using -.Xr poweroff 8 . -If the powerdown fails, or the system does not support software powerdown, -the system will simply halt instead. -.It Fl r -The system is rebooted at the specified -.Ar time , -using -.Xr reboot 8 . -.It Fl v -To enable verbose messages on the console, pass -.Fl v -to -.Xr reboot 8 -or -.Xr halt 8 . -.It Fl x -To enable debugging messages on the console, pass -.Fl x -to -.Xr reboot 8 -or -.Xr halt 8 . -.It Fl z -To silence some shutdown messages on the console, pass -.Fl z -to -.Xr reboot 8 -or -.Xr halt 8 . -.It Fl D -Prevents -.Nm -from detaching from the tty with -.Xr fork 2 Ns / -.Xr exit 3 . -.It Ar time -.Ar Time -is the time at which -.Nm -will bring the system down and -may be the word -.Ar now -or a future time in one of two formats: -.Ar +number , -or -.Ar [[[[[cc]yy]mm]dd]hh]mm , -where the century, year, month, day, and hour may be defaulted -to the current system values. -The first form brings the system down -.Ar number -minutes from the current time; the second brings the system down at the -absolute time specified. -If the century is not specified, it defaults to 1900 for years between 69 -and 99, or 2000 for years between 0 and 68. -A leading zero in the -.Dq yy -value is -.Em not -optional. -.It Ar message ... -Any other arguments comprise the warning message that is broadcast -to users currently logged into the system. -.It Ar - -If -.Ar - -is supplied as the only argument after the time, the warning message is read -from the standard input. -.El -.Sh BEHAVIOR -.Pp -At intervals, becoming more frequent as apocalypse approaches -and starting at ten hours before shutdown, warning messages are displayed -on the terminals of all users logged in. -Five minutes before shutdown, or immediately if shutdown is in less -than 5 minutes, logins are disabled by creating -.Pa /etc/nologin -and copying the warning message there. -If this file exists when a user attempts to log in, -.Xr login 1 -prints its contents and exits. -The file is removed just before -.Nm -exits. -.Pp -At shutdown time, a message is written in the system log containing the -time of shutdown, who initiated the shutdown, and the reason. -Next a message is printed announcing the start of the system shutdown hooks. -Then the shutdown hooks in -.Pa /etc/rc.shutdown -are run, and a message is printed indicating that they have completed. -After a short delay, -.Nm -runs -.Xr halt 8 -or -.Xr reboot 8 , -or sends a terminate -signal to -.Xr init 8 -to bring the system down to single-user mode, depending on the choice -of options. -.Pp -The time of the shutdown and the warning message are placed in -.Pa /etc/nologin -and should be used to tell the users why the system is -going down, when it will be back up, and to share any other pertinent -information. -.Sh FILES -.Bl -tag -width /etc/rc.shutdown -compact -.It Pa /etc/nologin -tells -.Xr login 1 -not to let anyone log in -.It Pa /fastboot -tells -.Xr rc 8 -not to run -.Xr fsck 8 -when rebooting -.It Pa /etc/rc.shutdown -System shutdown commands -.El -.Sh SEE ALSO -.Xr login 1 , -.Xr wall 1 , -.Xr fastboot 8 , -.Xr halt 8 , -.Xr init 8 , -.Xr poweroff 8 , -.Xr reboot 8 , -.Xr rescue 8 -.Sh BACKWARD COMPATIBILITY -The hours and minutes in the second time format may be separated by -a colon (``:'') for backward compatibility. -.Sh HISTORY -A -.Nm -command was originally written by Ian Johnstone for UNSW's modified -.At "6th Edn" , -modified, and then incorporated in -.Bx 4.1 . diff --git a/sbin/shutdown/shutdown.c b/sbin/shutdown/shutdown.c deleted file mode 100644 index 18dc996f6..000000000 --- a/sbin/shutdown/shutdown.c +++ /dev/null @@ -1,592 +0,0 @@ -/* $NetBSD: shutdown.c,v 1.56 2014/03/28 18:27:14 apb Exp $ */ - -/* - * Copyright (c) 1988, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1988, 1990, 1993\ - The Regents of the University of California. All rights reserved."); -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)shutdown.c 8.4 (Berkeley) 4/28/95"; -#else -__RCSID("$NetBSD: shutdown.c,v 1.56 2014/03/28 18:27:14 apb Exp $"); -#endif -#endif /* not lint */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pathnames.h" - -#ifdef DEBUG -#undef _PATH_NOLOGIN -#define _PATH_NOLOGIN "./nologin" -#undef _PATH_FASTBOOT -#define _PATH_FASTBOOT "./fastboot" -#endif - -#define H *60*60 -#define M *60 -#define S *1 -#define NOLOG_TIME 5*60 -static const struct interval { - time_t timeleft, timetowait; -} tlist[] = { - { 10 H, 5 H }, { 5 H, 3 H }, { 2 H, 1 H }, { 1 H, 30 M }, - { 30 M, 10 M }, { 20 M, 10 M }, { 10 M, 5 M }, { 5 M, 3 M }, - { 2 M, 1 M }, { 1 M, 30 S }, { 30 S, 30 S }, - { 0, 0 } -}; -#undef H -#undef M -#undef S - -static time_t offset, shuttime; -static int dofast, dohalt, doreboot, killflg, nofork, nosync, dodump; -static size_t mbuflen; -static int dopowerdown; -static int dodebug, dosilent, doverbose; -static const char *whom; -static char mbuf[BUFSIZ]; -static char *bootstr; - -static void badtime(void) __dead; -static void die_you_gravy_sucking_pig_dog(void) __dead; -static void doitfast(void); -static void dorcshutdown(void); -static void finish(int) __dead; -static void getoffset(char *); -static void loop(void) __dead; -static void nolog(void); -static void timeout(int) __dead; -static void timewarn(time_t); -static void usage(void) __dead; - -int -main(int argc, char *argv[]) -{ - char *p, *endp; - struct passwd *pw; - size_t arglen, len; - int ch; - - (void)setprogname(argv[0]); -#ifndef DEBUG - if (geteuid()) - errx(1, "%s: Not super-user", strerror(EPERM)); -#endif - while ((ch = getopt(argc, argv, "b:Ddfhknprvxz")) != -1) - switch (ch) { - case 'b': - bootstr = optarg; - break; - case 'd': - dodump = 1; - break; - case 'D': - nofork = 1; - break; - case 'f': - dofast = 1; - break; - case 'p': - dopowerdown = 1; - /* FALLTHROUGH */ - case 'h': - dohalt = 1; - break; - case 'k': - killflg = 1; - break; - case 'n': - nosync = 1; - break; - case 'r': - doreboot = 1; - break; - case 'v': - doverbose = 1; - break; - case 'x': - dodebug = 1; - break; - case 'z': - dosilent = 1; - break; - case '?': - default: - usage(); - } - argc -= optind; - argv += optind; - - if (argc < 1) - usage(); - - if (dodump && !dohalt && !doreboot) - doreboot = 1; - - if (dofast && nosync) { - warnx("Incompatible options -f and -n"); - usage(); - } - if (dohalt && doreboot) { - const char *which_flag = dopowerdown ? "p" : "h"; - - warnx("Incompatible options -%s and -r", which_flag); - usage(); - } - - getoffset(*argv++); - - if (argv[0]) { - if (strcmp(argv[0], "-") || argv[1]) { - for (p = mbuf, len = sizeof(mbuf); *argv; ++argv) { - arglen = strlen(*argv); - if ((len -= arglen) <= 2) - break; - if (p != mbuf) - *p++ = ' '; - (void)memmove(p, *argv, arglen); - p += arglen; - } - *p = '\n'; - *++p = '\0'; - } else { - p = mbuf; - endp = mbuf + sizeof(mbuf) - 2; - for (;;) { - if (!fgets(p, endp - p + 1, stdin)) - break; - for (; *p && p < endp; ++p); - if (p == endp) { - *p = '\n'; - *++p = '\0'; - break; - } - } - } - } - mbuflen = strlen(mbuf); - - if (offset) - (void)printf("Shutdown at %.24s.\n", ctime(&shuttime)); - else - (void)printf("Shutdown NOW!\n"); - - if (!(whom = getlogin())) - whom = (pw = getpwuid(getuid())) ? pw->pw_name : "???"; - -#ifdef DEBUG - (void)putc('\n', stdout); -#else - (void)setpriority(PRIO_PROCESS, 0, PRIO_MIN); - if (nofork == 0) { - int forkpid; - - forkpid = fork(); - if (forkpid == -1) { - perror("shutdown: fork"); - exit(1); - } - if (forkpid) { - (void)printf("shutdown: [pid %d]\n", forkpid); - exit(0); - } - (void)setsid(); - } -#endif - openlog("shutdown", LOG_CONS, LOG_AUTH); - loop(); - /* NOTREACHED */ -#ifdef __GNUC__ - return 1; -#endif -} - -static void -loop(void) -{ - const struct interval *tp; - u_int sltime; - int logged; - - if (offset <= NOLOG_TIME) { - logged = 1; - nolog(); - } - else - logged = 0; - tp = tlist; - if (tp->timeleft < offset) - (void)sleep((u_int)(offset - tp->timeleft)); - else { - while (offset < tp->timeleft) - ++tp; - /* - * Warn now, if going to sleep more than a fifth of - * the next wait time. - */ - if ((sltime = offset - tp->timeleft) != 0) { - if (sltime > tp->timetowait / 5) - timewarn(offset); - (void)sleep(sltime); - } - } - for (;; ++tp) { - timewarn(tp->timeleft); - if (!logged && tp->timeleft <= NOLOG_TIME) { - logged = 1; - nolog(); - } - (void)sleep((u_int)tp->timetowait); - if (!tp->timeleft) - break; - } - die_you_gravy_sucking_pig_dog(); -} - -static jmp_buf alarmbuf; - -static void -timewarn(time_t timeleft) -{ - static int first; - static char hostname[MAXHOSTNAMELEN + 1]; - FILE *pf; - char wcmd[MAXPATHLEN + 4]; - - if (!first++) { - (void)gethostname(hostname, sizeof(hostname)); - hostname[sizeof(hostname) - 1] = '\0'; - } - - /* undoc -n option to wall suppresses normal wall banner */ - (void)snprintf(wcmd, sizeof wcmd, "%s -n", _PATH_WALL); - if ((pf = popen(wcmd, "w")) == NULL) { - syslog(LOG_ERR, "%s: Can't find `%s' (%m)", getprogname(), - _PATH_WALL); - return; - } - - (void)fprintf(pf, - "\007*** %sSystem shutdown message from %s@%s ***\007\n", - timeleft ? "": "FINAL ", whom, hostname); - - if (timeleft > 10*60) - (void)fprintf(pf, "System going down at %5.5s\n\n", - ctime(&shuttime) + 11); - else if (timeleft > 59) - (void)fprintf(pf, "System going down in %ld minute%s\n\n", - (long)timeleft / 60, (timeleft > 60) ? "s" : ""); - else if (timeleft) - (void)fprintf(pf, "System going down in 30 seconds\n\n"); - else - (void)fprintf(pf, "System going down IMMEDIATELY\n\n"); - - if (mbuflen) - (void)fwrite(mbuf, 1, mbuflen, pf); - - /* - * play some games, just in case wall doesn't come back - * probably unnecessary, given that wall is careful. - */ - if (!setjmp(alarmbuf)) { - (void)signal(SIGALRM, timeout); - (void)alarm((u_int)30); - (void)pclose(pf); - (void)alarm((u_int)0); - (void)signal(SIGALRM, SIG_DFL); - } -} - -static void -/*ARGSUSED*/ -timeout(int signo) -{ - longjmp(alarmbuf, 1); -} - -static void -die_you_gravy_sucking_pig_dog(void) -{ - const char *what; - - if (doreboot) { - what = "reboot"; - } else if (dohalt && dopowerdown) { - what = "poweroff"; - } else if (dohalt) { - what = "halt"; - } else { - what = "shutdown"; - } - - syslog(LOG_NOTICE, "%s by %s: %s", what, whom, mbuf); - (void)sleep(2); - - (void)printf("\r\nSystem shutdown time has arrived\007\007\r\n"); - if (killflg) { - (void)printf("\rbut you'll have to do it yourself\r\n"); - finish(0); - } - if (dofast) - doitfast(); - dorcshutdown(); - if (doreboot || dohalt) { - const char *args[20]; - const char **arg, *path; -#ifndef DEBUG - int serrno; -#endif - - arg = &args[0]; - if (doreboot) { - path = _PATH_REBOOT; - *arg++ = "reboot"; - } else { - path = _PATH_HALT; - *arg++ = "halt"; - } - if (doverbose) - *arg++ = "-v"; - if (dodebug) - *arg++ = "-x"; - if (dosilent) - *arg++ = "-z"; - if (dodump) - *arg++ = "-d"; - if (nosync) - *arg++ = "-n"; - if (dopowerdown) - *arg++ = "-p"; - *arg++ = "-l"; - if (bootstr) - *arg++ = bootstr; - *arg++ = 0; -#ifndef DEBUG - (void)unlink(_PATH_NOLOGIN); - (void)execve(path, __UNCONST(args), NULL); - serrno = errno; - syslog(LOG_ERR, "Can't exec `%s' (%m)", path); - errno = serrno; - warn("Can't exec `%s'", path); -#else - printf("%s", path); - for (arg = &args[0]; *arg; arg++) - printf(" %s", *arg); - printf("\n"); -#endif - } else { -#ifndef DEBUG - (void)kill(1, SIGTERM); /* to single user */ -#else - printf("kill 1\n"); -#endif - } - finish(0); -} - -#define ATOI2(s) ((s) += 2, ((s)[-2] - '0') * 10 + ((s)[-1] - '0')) - -static void -getoffset(char *timearg) -{ - struct tm *lt; - char *p; - time_t now; - int yearset; - - (void)time(&now); - if (!strcasecmp(timearg, "now")) { /* now */ - offset = 0; - shuttime = now; - return; - } - - if (*timearg == '+') { /* +minutes */ - if (!isdigit((unsigned char)*++timearg)) - badtime(); - offset = atoi(timearg) * 60; - shuttime = now + offset; - return; - } - - /* handle hh:mm by getting rid of the colon */ - for (p = timearg; *p; ++p) - if (!isascii(*p) || !isdigit((unsigned char)*p)) { - if (*p == ':' && strlen(p) == 3) { - p[0] = p[1]; - p[1] = p[2]; - p[2] = '\0'; - } - else - badtime(); - } - - (void)unsetenv("TZ"); /* OUR timezone */ - lt = localtime(&now); /* current time val */ - - lt->tm_sec = 0; - - yearset = 0; - switch (strlen(timearg)) { - case 12: - lt->tm_year = ATOI2(timearg) * 100 - TM_YEAR_BASE; - yearset = 1; - /* FALLTHROUGH */ - case 10: - if (yearset) { - lt->tm_year += ATOI2(timearg); - } else { - yearset = ATOI2(timearg); - if (yearset < 69) - lt->tm_year = yearset + 2000 - TM_YEAR_BASE; - else - lt->tm_year = yearset + 1900 - TM_YEAR_BASE; - } - /* FALLTHROUGH */ - case 8: - lt->tm_mon = ATOI2(timearg); - --lt->tm_mon; - /* FALLTHROUGH */ - case 6: - lt->tm_mday = ATOI2(timearg); - /* FALLTHROUGH */ - case 4: - lt->tm_hour = ATOI2(timearg); - /* FALLTHROUGH */ - case 2: - lt->tm_min = ATOI2(timearg); - break; - default: - badtime(); - } - - if ((shuttime = mktime(lt)) == -1) - badtime(); - if ((offset = shuttime - now) < 0) - errx(1, "time is already past"); -} - -static void -dorcshutdown(void) -{ - (void)printf("\r\nAbout to run shutdown hooks...\r\n"); -#ifndef DEBUG - (void)setuid(0); - (void)system(". " _PATH_RCSHUTDOWN); -#endif - (void)sleep(5); /* Give operator a chance to abort this. */ - (void)printf("\r\nDone running shutdown hooks.\r\n"); -} - -#define FSMSG "fastboot file for fsck\n" -static void -doitfast(void) -{ - int fastfd; - - if ((fastfd = open(_PATH_FASTBOOT, O_WRONLY|O_CREAT|O_TRUNC, - 0664)) >= 0) { - (void)write(fastfd, FSMSG, sizeof(FSMSG) - 1); - (void)close(fastfd); - } -} - -#define NOMSG "\n\nNO LOGINS: System going down at " -static void -nolog(void) -{ - int logfd; - char *ct; - - (void)unlink(_PATH_NOLOGIN); /* in case linked to another file */ - (void)signal(SIGINT, finish); - (void)signal(SIGHUP, finish); - (void)signal(SIGQUIT, finish); - (void)signal(SIGTERM, finish); - if ((logfd = open(_PATH_NOLOGIN, O_WRONLY|O_CREAT|O_TRUNC, - 0664)) >= 0) { - (void)write(logfd, NOMSG, sizeof(NOMSG) - 1); - ct = ctime(&shuttime); - (void)write(logfd, ct + 11, 5); - (void)write(logfd, "\n\n", 2); - (void)write(logfd, mbuf, strlen(mbuf)); - (void)close(logfd); - } -} - -static void -/*ARGSUSED*/ -finish(int signo) -{ - - if (!killflg) - (void)unlink(_PATH_NOLOGIN); - exit(0); -} - -static void -badtime(void) -{ - - warnx("illegal time format"); - usage(); -} - -static void -usage(void) -{ - - (void)fprintf(stderr, - "Usage: %s [-Ddfhknprvxz] [-b bootstr] time [message ... | -]\n", - getprogname()); - exit(1); -} diff --git a/sbin/sysctl/Makefile b/sbin/sysctl/Makefile deleted file mode 100644 index 8fb0a14d5..000000000 --- a/sbin/sysctl/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# $NetBSD: Makefile,v 1.21 2012/11/29 02:05:38 christos Exp $ -# @(#)Makefile 8.1 (Berkeley) 6/6/93 - -.include -#DBG=-g - -RUMPPRG=sysctl -MAN= sysctl.8 - -SRCS= sysctl.c - -.PATH: ${.CURDIR}/../../lib/libc/gen -CPPFLAGS+= -DRUMP_ACTION -RUMPSRCS+= sysctlbyname.c sysctlgetmibinfo.c - -.include diff --git a/sbin/sysctl/pathconf.c b/sbin/sysctl/pathconf.c deleted file mode 100644 index dd7bd4cb1..000000000 --- a/sbin/sysctl/pathconf.c +++ /dev/null @@ -1,229 +0,0 @@ -/* $NetBSD: pathconf.c,v 1.7 2004/03/25 19:36:27 atatat Exp $ */ - -/* - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char copyright[] = -"@(#) Copyright (c) 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)pathconf.c 8.1 (Berkeley) 6/6/93"; -#else -static char rcsid[] = "$NetBSD: pathconf.c,v 1.7 2004/03/25 19:36:27 atatat Exp $"; -#endif -#endif /* not lint */ - -#include -#include -#include - -#include -#include -#include -#include - -#define PC_NAMES { \ - { 0, 0 }, \ - { "link_max", CTLTYPE_INT }, \ - { "max_canon", CTLTYPE_INT }, \ - { "max_input", CTLTYPE_INT }, \ - { "name_max", CTLTYPE_INT }, \ - { "path_max", CTLTYPE_INT }, \ - { "pipe_buf", CTLTYPE_INT }, \ - { "chown_restricted", CTLTYPE_INT }, \ - { "no_trunc", CTLTYPE_INT }, \ - { "vdisable", CTLTYPE_INT }, \ -} -#define PC_MAXID 10 - -struct ctlname pcnames[] = PC_NAMES; -char names[BUFSIZ]; - -struct list { - struct ctlname *list; - int size; -}; -struct list pclist = { pcnames, PC_MAXID }; - -int Aflag, aflag, nflag, wflag, stdinflag; - -int -main(argc, argv) - int argc; - char *argv[]; -{ - char *path; - int ch; - - while ((ch = getopt(argc, argv, "Aan")) != -1) { - switch (ch) { - - case 'A': - Aflag = 1; - break; - - case 'a': - aflag = 1; - break; - - case 'n': - nflag = 1; - break; - - default: - usage(); - } - } - argc -= optind; - argv += optind; - - if (argc == 0) - usage(); - path = *argv++; - if (strcmp(path, "-") == 0) - stdinflag = 1; - argc--; - if (Aflag || aflag) { - listall(path, &pclist); - exit(0); - } - if (argc == 0) - usage(); - while (argc-- > 0) - parse(path, *argv, 1); - exit(0); -} - -/* - * List all variables known to the system. - */ -listall(path, lp) - char *path; - struct list *lp; -{ - int lvl2; - - if (lp->list == 0) - return; - for (lvl2 = 0; lvl2 < lp->size; lvl2++) { - if (lp->list[lvl2].ctl_name == 0) - continue; - parse(path, lp->list[lvl2].ctl_name, Aflag); - } -} - -/* - * Parse a name into an index. - * Lookup and print out the attribute if it exists. - */ -parse(pathname, string, flags) - char *pathname; - char *string; - int flags; -{ - int indx, value; - char *bufp, buf[BUFSIZ]; - - bufp = buf; - snprintf(buf, BUFSIZ, "%s", string); - if ((indx = findname(string, "top", &bufp, &pclist)) == -1) - return; - if (bufp) { - fprintf(stderr, "name %s in %s is unknown\n", *bufp, string); - return; - } - if (stdinflag) - value = fpathconf(0, indx); - else - value = pathconf(pathname, indx); - if (value == -1) { - if (flags == 0) - return; - switch (errno) { - case EOPNOTSUPP: - fprintf(stderr, "%s: value is not available\n", string); - return; - case ENOTDIR: - fprintf(stderr, "%s: specification is incomplete\n", - string); - return; - case ENOMEM: - fprintf(stderr, "%s: type is unknown to this program\n", - string); - return; - default: - perror(string); - return; - } - } - if (!nflag) - fprintf(stdout, "%s = ", string); - fprintf(stdout, "%d\n", value); -} - -/* - * Scan a list of names searching for a particular name. - */ -findname(string, level, bufp, namelist) - char *string; - const char *level; - char **bufp; - struct list *namelist; -{ - char *name; - int i; - - if (namelist->list == 0 || (name = strsep(bufp, ".")) == NULL) { - fprintf(stderr, "%s: incomplete specification\n", string); - return (-1); - } - for (i = 0; i < namelist->size; i++) - if (namelist->list[i].ctl_name != NULL && - strcmp(name, namelist->list[i].ctl_name) == 0) - break; - if (i == namelist->size) { - fprintf(stderr, "%s level name %s in %s is invalid\n", - level, name, string); - return (-1); - } - return (i); -} - -usage() -{ - - (void)fprintf(stderr, "usage:\t%s\n\t%s\n\t%s\n", - "pathname [-n] variable ...", - "pathname [-n] -a", "pathname [-n] -A"); - exit(1); -} diff --git a/sbin/sysctl/prog_ops.h b/sbin/sysctl/prog_ops.h deleted file mode 100644 index f57426858..000000000 --- a/sbin/sysctl/prog_ops.h +++ /dev/null @@ -1,50 +0,0 @@ -/* $NetBSD: prog_ops.h,v 1.2 2010/12/13 21:48:01 pooka Exp $ */ - -/* - * Copyright (c) 2010 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _PROG_OPS_H_ -#define _PROG_OPS_H_ - -#include - -#ifndef CRUNCHOPS -struct prog_ops { - int (*op_init)(void); - - int (*op_sysctl)(const int *, u_int, void *, size_t *, - const void *, size_t); -}; -extern const struct prog_ops prog_ops; - -#define prog_init prog_ops.op_init -#define prog_sysctl prog_ops.op_sysctl -#else -#define prog_init ((int (*)(void))NULL) -#define prog_sysctl sysctl -#endif - -#endif /* _PROG_OPS_H_ */ diff --git a/sbin/sysctl/sysctl.8 b/sbin/sysctl/sysctl.8 deleted file mode 100644 index a16aa4f04..000000000 --- a/sbin/sysctl/sysctl.8 +++ /dev/null @@ -1,527 +0,0 @@ -.\" $NetBSD: sysctl.8,v 1.162 2011/08/03 01:47:40 christos Exp $ -.\" -.\" Copyright (c) 2004 The NetBSD Foundation, Inc. -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS -.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS -.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -.\" POSSIBILITY OF SUCH DAMAGE. -.\" -.\" -.\" Copyright (c) 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)sysctl.8 8.1 (Berkeley) 6/6/93 -.\" -.Dd August 2, 2011 -.Dt SYSCTL 8 -.Os -.Sh NAME -.Nm sysctl -.Nd get or set kernel state -.Sh SYNOPSIS -.Nm sysctl -.Op Fl AdeMnq -.Oo -.Fl r | -.Fl x -.Oc -.Op Ar name ... -.Nm sysctl -.Op Fl nq -.Oo -.Fl r | -.Fl x -.Oc -.Fl w -.Ar name Ns Li [?]= Ns Ar value ... -.Nm sysctl -.Op Fl en -.Oo -.Fl r | -.Fl x -.Oc -.Fl a -.Nm sysctl -.Op Fl nq -.Oo -.Fl r | -.Fl x -.Oc -.Fl f -.Ar file -.Sh DESCRIPTION -The -.Nm sysctl -utility retrieves kernel state and allows processes with -appropriate privilege to set kernel state. -The state to be retrieved or set is described using a -``Management Information Base'' (``MIB'') style name, -described as a dotted set of components. -The -.Sq / -character may also be used as a separator and a leading separator -character is accepted. -If -.Ar name -specifies a non-leaf node in the MIB, all the nodes underneath -.Ar name -will be printed. -.Pp -The following options are available: -.Bl -tag -width indent -.It Fl A -List all the known MIB names including tables, unless any MIB -arguments or -.Fl f Ar file -are given. -Those with string or integer values will be printed as with the -.Fl a -flag; for table or structure values that -.Nm -is not able to print, -the name of the utility to retrieve them is given. -Errors in retrieving or setting values will be directed to stdout -instead of stderr. -.It Fl a -List all the currently available string or integer values. -The use of a solitary separator character (either -.Sq \&. -or -.Sq / ) -by -itself has the same effect. -Any given -.Ar name -arguments are ignored if this option is specified. -.It Fl d -Descriptions of each of the nodes selected will be printed instead of -their values. -.It Fl e -Separate the name and the value of the variable(s) with -.Ql = . -This is useful for producing output which can be fed back to the -.Nm -utility. -This option is ignored if -.Fl n -is specified or a variable is being set. -.It Fl f -Specifies the name of a file to read and process. -Blank lines and comments (beginning with -.Ql # ) -are ignored. -Line continuations with -.Ql \e -are permitted. -Remaining lines are processed similarly to -command line arguments of the form -.Ar name -or -.Ar name Ns Li = Ns Ar value . -The -.Fl w -flag is implied by -.Fl f . -Any -.Ar name -arguments are ignored. -.It Fl M -Makes -.Nm -print the MIB instead of any of the actual values contained in the -MIB. -This causes the entire MIB to be printed unless specific MIB arguments -or -.Fl f Ar file -are also given. -.It Fl n -Specifies that the printing of the field name should be -suppressed and that only its value should be output. -This flag is useful for setting shell variables. -For example, to save the pagesize in variable psize, use: -.Bd -literal -offset indent -compact -set psize=`sysctl -n hw.pagesize` -.Ed -.It Fl q -Used to indicate that nothing should be printed for reads or writes unless an -error is detected. -For reads, not finding a variable does not print an error, but exits with -an error code. -This is useful just for testing that a variable exists. -.It Fl r -Raw output form. -Values printed are in their raw binary forms as retrieved directly -from the kernel. -Some additional nodes that -.Nm -cannot print directly can be retrieved with this flag. -This option conflicts with the -.Fl x -option. -.It Fl w -Sets the MIB style name given to the value given. -The MIB style name and value must be separated by -.Ql = -with no whitespace. -To prevent an error if the MIB style name does not exist (as would be the -case with optional kernel components), one can separate the MIB style name -and the value with -.Ql ?= . -Only integral and string values can be set via this method. -.It Fl x -Makes -.Nm -print the requested value in a hexadecimal representation instead of -its regular form. -If specified more than once, the output for each value resembles that of -.Xr hexdump 1 -when given the -.Fl C -flag. -This option conflicts with the -.Fl r -option. -.Pp -.El -The -.Ql proc -top-level MIB has a special semantic: it represent per-process values -and as such may differ from one process to another. -The second-level name is the pid of the process (in decimal form), -or the special word -.Ql curproc . -For variables below -.Ql proc. Ns Ao pid Ac Ns .rlimit , -the integer value may be replaced -with the string -.Ql unlimited -if it matches the magic value used to disable -a limit. -.Pp -The information available from -.Nm sysctl -consists of integers, strings, and tables. -The tabular information can only be retrieved by special -purpose programs such as -.Nm ps , -.Nm systat , -and -.Nm netstat . -See -.Xr sysctl 7 -for description of available MIBs. -.Sh CREATION AND DELETION -New nodes are allowed to be created by the superuser when the kernel -is running at security level 0. -These new nodes may refer to existing kernel data or to new data that -is only instrumented by -.Xr sysctl 3 -itself. -.Pp -The syntax for creating new nodes is -.Dq //create=new.node.path -followed by one or more of the following attributes separated by -commas. -The use of a double separator (both -.Sq / -and -.Sq \&. -can be used as -separators) as the prefix tells sysctl that the first series of tokens -is not a MIB name, but a command. -It is recommended that the double separator preceding the command not -be the same as the separator used in naming the MIB entry so as to -avoid possible parse conflicts. -The -.Dq value -assigned, if one is given, must be last. -.Pp -.Bl -bullet -compact -.It -.Ar type= Ns Aq Ar T -where -.Ar T -must be one of -.Dq node , -.Dq int , -.Dq string , -.Dq quad , -or -.Dq struct . -If the type is omitted, the -.Dq node -type is assumed. -.It -.Ar size= Ns Aq Ar S -here, -.Ar S -asserts the size of the new node. -Nodes of type -.Dq node -should not have a size set. -The size may be omitted for nodes of types -.Dq int -or -.Dq quad . -If the size is omitted for a node of type -.Dq string , -the size will be determined by the length of the given value, or by -the kernel for kernel strings. -Nodes of type -.Dq struct -must have their size explicitly set. -.It -.Ar addr= Ns Aq Ar A -or -.Ar symbol= Ns Aq Ar A -The kernel address of the data being instrumented. -If -.Dq symbol -is used, the symbol must be globally visible to the in-kernel -.Xr ksyms 4 -driver. -.It -.Ar n= Ns Aq Ar N -The MIB number to be assigned to the new node. -If no number is specified, the kernel will assign a value. -.It -.Ar flags= Ns Aq Ar F -A concatenated string of single letters that govern the behavior of -the node. -Flags currently available are: -.Bl -tag -width www -.It a -Allow anyone to write to the node, if it is writable. -.It h -.Dq Hidden . -.Nm -must be invoked with -.Fl A -or the hidden node must be specifically requested in order to see it -.It i -.Dq Immediate . -Makes the node store data in itself, rather than allocating new space -for it. -This is the default for nodes of type -.Dq int -and -.Dq quad . -This is the opposite of owning data. -.It o -.Dq Own . -When the node is created, separate space will be allocated to store -the data to be instrumented. -This is the default for nodes of type -.Dq string -and -.Dq struct -where it is not possible to guarantee sufficient space to store the -data in the node itself. -.It p -.Dq Private . -Nodes that are marked private, and children of nodes so marked, are -only viewable by the superuser. -Be aware that the immediate data that some nodes may store is not -necessarily protected by this. -.It x -.Dq Hexadecimal . -Make -.Nm -default to hexadecimal display of the retrieved value -.It r -.Dq Read-only . -The data instrumented by the given node is read-only. -Note that other mechanisms may still exist for changing the data. -This is the default for nodes that instrument data. -.It w -.Dq Writable . -The data instrumented by the given node is writable at any time. -This is the default for nodes that can have children. -.El -.Pp -.It -.Ar value= Ns Aq Ar V -An initial starting value for a new node that does not reference -existing kernel data. -Initial values can only be assigned for nodes of the -.Dq int , -.Dq quad , -and -.Dq string -types. -.El -.Pp -New nodes must fit the following set of criteria: -.Pp -.Bl -bullet -compact -.It -If the new node is to address an existing kernel object, only one of the -.Dq symbol -or -.Dq addr -arguments may be given. -.It -The size for a -.Dq struct -type node must be specified; no initial value is expected or permitted. -.It -Either the size or the initial value for a -.Dq string -node must be given. -.It -The node which will be the parent of the new node must be writable. -.El -.Pp -If any of the given parameters describes an invalid configuration, -.Nm -will emit a diagnostic message to the standard error and exit. -.Pp -Descriptions can be added by the super-user to any node that does not -have one, provided that the node is not marked with the -.Dq PERMANENT -flag. -The syntax is similar to the syntax for creating new nodes with the -exception of the keyword that follows the double separator at the -start of the command: -.Dq //describe=new.node.path=new node description . -Once a description has been added, it cannot be changed or removed. -.Pp -When destroying nodes, only the path to the node is necessary, i.e., -.Dq //destroy=old.node.path . -No other parameters are expected or permitted. -Nodes being destroyed must have no children, and their parent must be -writable. -Nodes that are marked with the -.Dq Dv PERMANENT -flag (as assigned by the kernel) may not be deleted. -.Pp -In all cases, the initial -.Sq = -that follows the command (eg, -.Dq create , -.Dq destroy , -or -.Dq describe ) -may be replaced with another instance of the separator character, -provided that the same separator character is used for the length of -the name specification. -.Sh FILES -.Bl -tag -width /etc/sysctl.conf -compact -.It Pa /etc/sysctl.conf -.Nm -variables set at boot time -.El -.Sh EXAMPLES -For example, to retrieve the maximum number of processes allowed -in the system, one would use the following request: -.Bd -literal -offset indent -compact -sysctl kern.maxproc -.Ed -.Pp -To set the maximum number of processes allowed -in the system to 1000, one would use the following request: -.Bd -literal -offset indent -compact -sysctl -w kern.maxproc=1000 -.Ed -.Pp -Information about the system clock rate may be obtained with: -.Bd -literal -offset indent -compact -sysctl kern.clockrate -.Ed -.Pp -Information about the load average history may be obtained with: -.Bd -literal -offset indent -compact -sysctl vm.loadavg -.Ed -.Pp -To view the values of the per-process variables of the current shell, -the request: -.Bd -literal -offset indent -compact -sysctl proc.$$ -.Ed -can be used if the shell interpreter replaces $$ with its pid (this is true -for most shells). -.Pp -To redirect core dumps to the -.Pa /var/tmp/ Ns Aq username -directory, -.Bd -literal -offset indent -compact -sysctl -w proc.$$.corename=/var/tmp/%u/%n.core -.Ed -should be used. -.Bd -literal -offset indent -compact -sysctl -w proc.curproc.corename=/var/tmp/%u/%n.core -.Ed -changes the value for the sysctl process itself, and will not have the desired -effect. -.Pp -To create the root of a new sub-tree called -.Dq local -add some children to the new node, and some descriptions: -.Bd -literal -offset indent -compact -sysctl -w //create=local -sysctl -w //describe=local=my local sysctl tree -sysctl -w //create=local.esm_debug,type=int,symbol=esm_debug,flags=w -sysctl -w //describe=local.esm_debug=esm driver debug knob -sysctl -w //create=local.audiodebug,type=int,symbol=audiodebug,flags=w -sysctl -w //describe=local.audiodebug=generic audio debug knob -.Ed -Note that the children are made writable so that the two debug -settings in question can be tuned arbitrarily. -.Pp -To destroy that same subtree: -.Bd -literal -offset indent -compact -sysctl -w //destroy=local.esm_debug -sysctl -w //destroy=local.audiodebug -sysctl -w //destroy=local -.Ed -.Sh SEE ALSO -.Xr sysctl 3 , -.Xr ksyms 4 , -.Xr sysctl 7 -.Sh HISTORY -.Nm sysctl -first appeared in -.Bx 4.4 . diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c deleted file mode 100644 index 925d6e6a3..000000000 --- a/sbin/sysctl/sysctl.c +++ /dev/null @@ -1,2800 +0,0 @@ -/* $NetBSD: sysctl.c,v 1.156 2015/08/17 06:42:46 knakahara Exp $ */ - -/*- - * Copyright (c) 2003 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Andrew Brown. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1993\ - The Regents of the University of California. All rights reserved."); -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)sysctl.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: sysctl.c,v 1.156 2015/08/17 06:42:46 knakahara Exp $"); -#endif -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef __minix -#include -#include -#include -#include -#include -#include -#endif /* !__minix */ -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "prog_ops.h" - -/* - * this needs to be able to do the printing and the setting - */ -#define HANDLER_PROTO const char *, const char *, char *, \ - int *, u_int, const struct sysctlnode *, \ - u_int, void * -#define HANDLER_ARGS const char *sname, const char *dname, char *value, \ - int *name, u_int namelen, const struct sysctlnode *pnode, \ - u_int type, void *v -#define DISPLAY_VALUE 0 -#define DISPLAY_OLD 1 -#define DISPLAY_NEW 2 - -/* - * generic routines - */ -static const struct handlespec *findhandler(const char *, regex_t *, size_t *); -static void canonicalize(const char *, char *); -static void purge_tree(struct sysctlnode *); -static void print_tree(int *, u_int, struct sysctlnode *, u_int, int, regex_t *, - size_t *); -static void write_number(int *, u_int, struct sysctlnode *, char *); -static void write_string(int *, u_int, struct sysctlnode *, char *); -static void display_number(const struct sysctlnode *, const char *, - const void *, size_t, int); -static void display_string(const struct sysctlnode *, const char *, - const void *, size_t, int); -static void display_struct(const struct sysctlnode *, const char *, - const void *, size_t, int); -static void hex_dump(const unsigned char *, size_t); -__dead static void usage(void); -static void parse(char *, regex_t *, size_t *); -static void parse_create(char *); -static void parse_destroy(char *); -static void parse_describe(char *); -static void getdesc1(int *, u_int, struct sysctlnode *); -static void getdesc(int *, u_int, struct sysctlnode *); -static void trim_whitespace(char *, int); -static void sysctlerror(int); -static void sysctlparseerror(u_int, const char *); -static void sysctlperror(const char *, ...) __printflike(1, 2); -#define EXIT(n) do { \ - if (fn == NULL) exit(n); else return; } while (/*CONSTCOND*/0) - -/* - * "borrowed" from libc:sysctlgetmibinfo.c - */ -int __learn_tree(int *, u_int, struct sysctlnode *); - -/* - * "handlers" - */ -static void printother(HANDLER_PROTO); -static void kern_clockrate(HANDLER_PROTO); -static void kern_boottime(HANDLER_PROTO); -static void kern_consdev(HANDLER_PROTO); -static void kern_cp_time(HANDLER_PROTO); -static void kern_cp_id(HANDLER_PROTO); -static void kern_drivers(HANDLER_PROTO); -static void vm_loadavg(HANDLER_PROTO); -static void proc_limit(HANDLER_PROTO); -#ifdef CPU_DISKINFO -static void machdep_diskinfo(HANDLER_PROTO); -#endif /* CPU_DISKINFO */ -static void mode_bits(HANDLER_PROTO); -static void reserve(HANDLER_PROTO); - -static const struct handlespec { - const char *ps_re; - void (*ps_p)(HANDLER_PROTO); - void (*ps_w)(HANDLER_PROTO); - const void *ps_d; -} handlers[] = { - { "/kern/clockrate", kern_clockrate, NULL, NULL }, - { "/kern/evcnt", printother, NULL, "vmstat -e" }, - { "/kern/vnode", printother, NULL, "pstat" }, - { "/kern/proc(2|_args)?", printother, NULL, "ps" }, - { "/kern/file2?", printother, NULL, "pstat" }, - { "/kern/ntptime", printother, NULL, - "ntpdc -c kerninfo" }, - { "/kern/msgbuf", printother, NULL, "dmesg" }, - { "/kern/boottime", kern_boottime, NULL, NULL }, - { "/kern/consdev", kern_consdev, NULL, NULL }, - { "/kern/cp_time(/[0-9]+)?", kern_cp_time, NULL, NULL }, - { "/kern/sysvipc_info", printother, NULL, "ipcs" }, - { "/kern/cp_id(/[0-9]+)?", kern_cp_id, NULL, NULL }, - - { "/kern/coredump/setid/mode", mode_bits, mode_bits, NULL }, - { "/kern/drivers", kern_drivers, NULL, NULL }, - - { "/kern/intr/list", printother, NULL, "intrctl" }, - { "/kern/intr/affinity", printother, NULL, "intrctl" }, - { "/kern/intr/intr", printother, NULL, "intrctl" }, - { "/kern/intr/nointr", printother, NULL, "intrctl" }, - - { "/vm/vmmeter", printother, NULL, - "vmstat' or 'systat" }, - { "/vm/loadavg", vm_loadavg, NULL, NULL }, - { "/vm/uvmexp2?", printother, NULL, - "vmstat' or 'systat" }, - - { "/vfs/nfs/nfsstats", printother, NULL, "nfsstat" }, - - { "/net/inet6?/tcp6?/ident", printother, NULL, "identd" }, - { "/net/inet6/icmp6/nd6_[dp]rlist", printother, NULL, "ndp" }, - { "/net/key/dumps[ap]", printother, NULL, "setkey" }, - { "/net/[^/]+/[^/]+/pcblist", printother, NULL, - "netstat' or 'sockstat" }, - { "/net/(inet|inet6)/[^/]+/stats", printother, NULL, "netstat"}, - { "/net/bpf/(stats|peers)", printother, NULL, "netstat"}, - - { "/net/inet.*/tcp.*/deb.*", printother, NULL, "trpt" }, - - { "/net/inet.*/ip.*/anonportalgo/reserve", reserve, reserve, NULL }, - - { "/net/ns/spp/deb.*", printother, NULL, "trsp" }, - - { "/hw/diskstats", printother, NULL, "iostat" }, - -#ifdef CPU_CONSDEV - { "/machdep/consdev", kern_consdev, NULL, NULL }, -#endif /* CPU_CONSDEV */ -#ifdef CPU_DISKINFO - { "/machdep/diskinfo", machdep_diskinfo, NULL, NULL }, -#endif /* CPU_CONSDEV */ - - { "/proc/[^/]+/rlimit/[^/]+/[^/]+", proc_limit, proc_limit, NULL }, - - /* - * these will only be called when the given node has no children - */ - { "/net/[^/]+", printother, NULL, NULL }, - { "/debug", printother, NULL, NULL }, - { "/ddb", printother, NULL, NULL }, - { "/vendor", printother, NULL, NULL }, - - { NULL, NULL, NULL, NULL }, -}; - -struct sysctlnode my_root = { - .sysctl_flags = SYSCTL_VERSION|CTLFLAG_ROOT|CTLTYPE_NODE, - .sysctl_size = sizeof(struct sysctlnode), - .sysctl_num = 0, - .sysctl_name = "(prog_root)", -}; - -int Aflag, aflag, dflag, Mflag, nflag, qflag, rflag, wflag, xflag; -size_t nr; -char *fn; -int req, stale, errs; -FILE *warnfp = stderr; - -#define MAXPORTS 0x10000 - -/* - * vah-riables n stuff - */ -char gsname[SYSCTL_NAMELEN * CTL_MAXNAME + CTL_MAXNAME], - canonname[SYSCTL_NAMELEN * CTL_MAXNAME + CTL_MAXNAME], - gdname[10 * CTL_MAXNAME + CTL_MAXNAME]; -char sep[] = "."; -const char *eq = " = "; -const char *lname[] = { - "top", "second", "third", "fourth", "fifth", "sixth", - "seventh", "eighth", "ninth", "tenth", "eleventh", "twelfth" -}; - -/* - * you've heard of main, haven't you? - */ -int -main(int argc, char *argv[]) -{ - int name[CTL_MAXNAME]; - int ch; - size_t lastcompiled = 0; - regex_t *re; - - setprogname(argv[0]); - while ((ch = getopt(argc, argv, "Aabdef:Mnqrwx")) != -1) { - switch (ch) { - case 'A': - Aflag++; - break; - case 'a': - aflag++; - break; - case 'd': - dflag++; - break; - case 'e': - eq = "="; - break; - case 'f': - fn = optarg; - wflag++; - break; - case 'M': - Mflag++; - break; - case 'n': - nflag++; - break; - case 'q': - qflag++; - break; - case 'b': /* FreeBSD compat */ - case 'r': - rflag++; - break; - case 'w': - wflag++; - break; - case 'x': - xflag++; - break; - default: - usage(); - } - } - - argc -= optind; - argv += optind; - - if (xflag && rflag) - usage(); - /* if ((xflag || rflag) && wflag) - usage(); */ - /* if (aflag && (Mflag || qflag)) - usage(); */ - if ((aflag || Aflag) && qflag) - usage(); - if ((Aflag || Mflag || dflag) && argc == 0 && fn == NULL) - aflag = 1; - - if (prog_init && prog_init() == -1) - err(EXIT_FAILURE, "prog init failed"); - - if (Aflag) - warnfp = stdout; - stale = req = 0; - - if ((re = malloc(sizeof(*re) * __arraycount(handlers))) == NULL) - err(EXIT_FAILURE, "malloc regex"); - - if (aflag) { - print_tree(&name[0], 0, NULL, CTLTYPE_NODE, 1, - re, &lastcompiled); - /* if (argc == 0) */ - return (0); - } - - if (fn) { - FILE *fp; - char *l; - - fp = fopen(fn, "r"); - if (fp == NULL) { - err(EXIT_FAILURE, "%s", fn); - } else { - nr = 0; - while ((l = fparseln(fp, NULL, &nr, NULL, 0)) != NULL) - { - if (*l) { - parse(l, re, &lastcompiled); - free(l); - } - } - fclose(fp); - } - return errs ? 1 : 0; - } - - if (argc == 0) - usage(); - - while (argc-- > 0) - parse(*argv++, re, &lastcompiled); - - return errs ? EXIT_FAILURE : EXIT_SUCCESS; -} - -/* - * ******************************************************************** - * how to find someone special to handle the reading (or maybe even - * writing) of a particular node - * ******************************************************************** - */ -static const struct handlespec * -findhandler(const char *s, regex_t *re, size_t *lastcompiled) -{ - const struct handlespec *p; - size_t i, l; - int j; - char eb[64]; - regmatch_t match; - - p = &handlers[0]; - l = strlen(s); - for (i = 0; p[i].ps_re != NULL; i++) { - if (i >= *lastcompiled) { - j = regcomp(&re[i], p[i].ps_re, REG_EXTENDED); - if (j != 0) { - regerror(j, &re[i], eb, sizeof(eb)); - errx(EXIT_FAILURE, "regcomp: %s: %s", p[i].ps_re, eb); - } - *lastcompiled = i + 1; - } - j = regexec(&re[i], s, 1, &match, 0); - if (j == 0) { - if (match.rm_so == 0 && match.rm_eo == (int)l) - return &p[i]; - } - else if (j != REG_NOMATCH) { - regerror(j, &re[i], eb, sizeof(eb)); - errx(EXIT_FAILURE, "regexec: %s: %s", p[i].ps_re, eb); - } - } - - return NULL; -} - -/* - * after sysctlgetmibinfo is done with the name, we convert all - * separators to / and stuff one at the front if it was missing - */ -static void -canonicalize(const char *i, char *o) -{ - const char *t; - char p[SYSCTL_NAMELEN + 1]; - int l; - - if (i[0] != *sep) { - o[0] = '/'; - o[1] = '\0'; - } - else - o[0] = '\0'; - - t = i; - do { - i = t; - t = strchr(i, sep[0]); - if (t == NULL) - strcat(o, i); - else { - l = t - i; - t++; - memcpy(p, i, l); - p[l] = '\0'; - strcat(o, p); - strcat(o, "/"); - } - } while (t != NULL); -} - -/* - * ******************************************************************** - * convert this special number to a special string so we can print the - * mib - * ******************************************************************** - */ -static const char * -sf(u_int f) -{ - static char s[256]; - const char *c; - - s[0] = '\0'; - c = ""; - -#define print_flag(_f, _s, _c, _q, _x) \ - if (((_f) & (__CONCAT(CTLFLAG_,_x))) == (__CONCAT(CTLFLAG_,_q))) { \ - strlcat((_s), (_c), sizeof(_s)); \ - strlcat((_s), __STRING(_q), sizeof(_s)); \ - (_c) = ","; \ - (_f) &= ~(__CONCAT(CTLFLAG_,_x)); \ - } - print_flag(f, s, c, READONLY, READWRITE); - print_flag(f, s, c, READWRITE, READWRITE); - print_flag(f, s, c, ANYWRITE, ANYWRITE); - print_flag(f, s, c, PRIVATE, PRIVATE); - print_flag(f, s, c, PERMANENT, PERMANENT); - print_flag(f, s, c, OWNDATA, OWNDATA); - print_flag(f, s, c, IMMEDIATE, IMMEDIATE); - print_flag(f, s, c, HEX, HEX); - print_flag(f, s, c, ROOT, ROOT); - print_flag(f, s, c, ANYNUMBER, ANYNUMBER); - print_flag(f, s, c, HIDDEN, HIDDEN); - print_flag(f, s, c, ALIAS, ALIAS); -#undef print_flag - - if (f) { - char foo[9]; - snprintf(foo, sizeof(foo), "%x", f); - strlcat(s, c, sizeof(s)); - strlcat(s, foo, sizeof(s)); - } - - return (s); -} - -static const char * -st(u_int t) -{ - - switch (t) { - case CTLTYPE_NODE: - return "NODE"; - case CTLTYPE_INT: - return "INT"; - case CTLTYPE_STRING: - return "STRING"; - case CTLTYPE_QUAD: - return "QUAD"; - case CTLTYPE_STRUCT: - return "STRUCT"; - case CTLTYPE_BOOL: - return "BOOL"; - } - - return "???"; -} - -/* - * ******************************************************************** - * recursively eliminate all data belonging to the given node - * ******************************************************************** - */ -static void -purge_tree(struct sysctlnode *rnode) -{ - struct sysctlnode *node; - - if (rnode == NULL || - SYSCTL_TYPE(rnode->sysctl_flags) != CTLTYPE_NODE || - rnode->sysctl_child == NULL) - return; - - for (node = rnode->sysctl_child; - node < &rnode->sysctl_child[rnode->sysctl_clen]; - node++) - purge_tree(node); - free(rnode->sysctl_child); - rnode->sysctl_csize = 0; - rnode->sysctl_clen = 0; - rnode->sysctl_child = NULL; - - if (rnode->sysctl_desc == (const char*)-1) - rnode->sysctl_desc = NULL; - if (rnode->sysctl_desc != NULL) - free(__UNCONST(rnode->sysctl_desc)); - rnode->sysctl_desc = NULL; -} - -static void __attribute__((__format__(__printf__, 3, 4))) -appendprintf(char **bp, size_t *lbp, const char *fmt, ...) -{ - int r; - va_list ap; - - va_start(ap, fmt); - r = vsnprintf(*bp, *lbp, fmt, ap); - va_end(ap); - if (r < 0 || (size_t)r > *lbp) - r = *lbp; - *bp += r; - *lbp -= r; -} - -/* - * ******************************************************************** - * print this node and any others underneath it - * ******************************************************************** - */ -static void -print_tree(int *name, u_int namelen, struct sysctlnode *pnode, u_int type, - int add, regex_t *re, size_t *lastcompiled) -{ - struct sysctlnode *node; - int rc; - size_t ni, sz, ldp, lsp; - char *sp, *dp, *tsp, *tdp; - const struct handlespec *p; - - sp = tsp = &gsname[strlen(gsname)]; - dp = tdp = &gdname[strlen(gdname)]; - ldp = sizeof(gdname) - (dp - gdname); - lsp = sizeof(gsname) - (sp - gsname); - - if (sp != &gsname[0] && dp == &gdname[0]) { - /* - * aw...shucks. now we must play catch up - */ - for (ni = 0; ni < namelen; ni++) - appendprintf(&tdp, &ldp, "%s%d", ni > 0 ? "." : "", - name[ni]); - } - - if (pnode == NULL) - pnode = &my_root; - else if (add) { - appendprintf(&tsp, &lsp, "%s%s", namelen > 1 ? sep : "", - pnode->sysctl_name); - appendprintf(&tdp, &ldp, "%s%d", namelen > 1 ? "." : "", - pnode->sysctl_num); - } - - if (Mflag && pnode != &my_root) { - if (nflag) - printf("%s: ", gdname); - else - printf("%s (%s): ", gsname, gdname); - printf("CTLTYPE_%s", st(type)); - if (type == CTLTYPE_NODE) { - if (SYSCTL_FLAGS(pnode->sysctl_flags) & CTLFLAG_ALIAS) - printf(", alias %d", - pnode->sysctl_alias); - else - printf(", children %d/%d", - pnode->sysctl_clen, - pnode->sysctl_csize); - } - printf(", size %zu", pnode->sysctl_size); - printf(", flags 0x%x<%s>", - SYSCTL_FLAGS(pnode->sysctl_flags), - sf(SYSCTL_FLAGS(pnode->sysctl_flags))); - if (pnode->sysctl_func) - printf(", func=%p", pnode->sysctl_func); - printf(", ver=%d", pnode->sysctl_ver); - printf("\n"); - if (type != CTLTYPE_NODE) { - *sp = *dp = '\0'; - return; - } - } - - if (dflag && pnode != &my_root) { - if (Aflag || type != CTLTYPE_NODE) { - if (pnode->sysctl_desc == NULL) - getdesc1(name, namelen, pnode); - if (Aflag || !add || - (pnode->sysctl_desc != NULL && - pnode->sysctl_desc != (const char*)-1)) { - if (!nflag) - printf("%s: ", gsname); - if (pnode->sysctl_desc == NULL || - pnode->sysctl_desc == (const char*)-1) - printf("(no description)\n"); - else - printf("%s\n", pnode->sysctl_desc); - } - } - - if (type != CTLTYPE_NODE) { - *sp = *dp = '\0'; - return; - } - } - - /* - * if this is an alias and we added our name, that means we - * got here by recursing down into the tree, so skip it. The - * only way to print an aliased node is with either -M or by - * name specifically. - */ - if (SYSCTL_FLAGS(pnode->sysctl_flags) & CTLFLAG_ALIAS && add) { - *sp = *dp = '\0'; - return; - } - - canonicalize(gsname, canonname); - p = findhandler(canonname, re, lastcompiled); - if (type != CTLTYPE_NODE && p != NULL) { - if (p->ps_p == NULL) { - sysctlperror("Cannot print `%s': %s\n", gsname, - strerror(EOPNOTSUPP)); - exit(EXIT_FAILURE); - } - (*p->ps_p)(gsname, gdname, NULL, name, namelen, pnode, type, - __UNCONST(p->ps_d)); - *sp = *dp = '\0'; - return; - } - - if (type != CTLTYPE_NODE && pnode->sysctl_size == 0) { - rc = prog_sysctl(&name[0], namelen, NULL, &sz, NULL, 0); - if (rc == -1) { - sysctlerror(1); - *sp = *dp = '\0'; - return; - } - if (sz == 0) { - if ((Aflag || req) && !Mflag) - printf("%s: node contains no data\n", gsname); - *sp = *dp = '\0'; - return; - } - } - else - sz = pnode->sysctl_size; - - switch (type) { - case CTLTYPE_NODE: { - __learn_tree(name, namelen, pnode); - node = pnode->sysctl_child; - if (node == NULL) { - if (dflag) - /* do nothing */; - else if (p != NULL) - (*p->ps_p)(gsname, gdname, NULL, name, namelen, - pnode, type, __UNCONST(p->ps_d)); - else if ((Aflag || req) && !Mflag) - printf("%s: no children\n", gsname); - } - else { - if (dflag) - /* - * get all descriptions for next level - * in one chunk - */ - getdesc(name, namelen, pnode); - req = 0; - for (ni = 0; ni < pnode->sysctl_clen; ni++) { - name[namelen] = node[ni].sysctl_num; - if ((node[ni].sysctl_flags & CTLFLAG_HIDDEN) && - !(Aflag || req)) - continue; - print_tree(name, namelen + 1, &node[ni], - SYSCTL_TYPE(node[ni].sysctl_flags), - 1, re, lastcompiled); - } - } - break; - } - case CTLTYPE_INT: { - int i; - rc = prog_sysctl(name, namelen, &i, &sz, NULL, 0); - if (rc == -1) { - sysctlerror(1); - break; - } - display_number(pnode, gsname, &i, sizeof(i), DISPLAY_VALUE); - break; - } - case CTLTYPE_BOOL: { - bool b; - rc = prog_sysctl(name, namelen, &b, &sz, NULL, 0); - if (rc == -1) { - sysctlerror(1); - break; - } - display_number(pnode, gsname, &b, sizeof(b), DISPLAY_VALUE); - break; - } - case CTLTYPE_STRING: { - unsigned char buf[1024], *tbuf; - tbuf = buf; - sz = sizeof(buf); - rc = prog_sysctl(&name[0], namelen, tbuf, &sz, NULL, 0); - if (rc == -1 && errno == ENOMEM) { - tbuf = malloc(sz); - if (tbuf == NULL) { - sysctlerror(1); - break; - } - rc = prog_sysctl(&name[0], namelen, tbuf, &sz, NULL, 0); - } - if (rc == -1) - sysctlerror(1); - else - display_string(pnode, gsname, tbuf, sz, DISPLAY_VALUE); - if (tbuf != buf) - free(tbuf); - break; - } - case CTLTYPE_QUAD: { - u_quad_t q; - sz = sizeof(q); - rc = prog_sysctl(&name[0], namelen, &q, &sz, NULL, 0); - if (rc == -1) { - sysctlerror(1); - break; - } - display_number(pnode, gsname, &q, sizeof(q), DISPLAY_VALUE); - break; - } - case CTLTYPE_STRUCT: { - /* - * we shouldn't actually get here, but if we - * do, would it be nice to have *something* to - * do other than completely ignore the - * request. - */ - unsigned char *d; - if ((d = malloc(sz)) == NULL) { - fprintf(warnfp, "%s: !malloc failed!\n", gsname); - break; - } - rc = prog_sysctl(&name[0], namelen, d, &sz, NULL, 0); - if (rc == -1) { - sysctlerror(1); - break; - } - display_struct(pnode, gsname, d, sz, DISPLAY_VALUE); - free(d); - break; - } - default: - /* should i print an error here? */ - break; - } - - *sp = *dp = '\0'; -} - -/* - * ******************************************************************** - * parse a request, possibly determining that it's a create or destroy - * request - * ******************************************************************** - */ -static void -parse(char *l, regex_t *re, size_t *lastcompiled) -{ - struct sysctlnode *node; - const struct handlespec *w; - int name[CTL_MAXNAME], dodesc = 0; - u_int namelen, type; - char *key, *value, *dot; - size_t sz; - bool optional = false; - - req = 1; - key = l; - - if ((value = strchr(l, '=')) != NULL) { - if (value > l && value[-1] == '?') { - value[-1] = '\0'; - optional = true; - } - *value++ = '\0'; - } - - if ((dot = strpbrk(key, "./")) == NULL) - sep[0] = '.'; - else - sep[0] = dot[0]; - sep[1] = '\0'; - - while (key[0] == sep[0] && key[1] == sep[0]) { - if (value != NULL) - value[-1] = '='; - if (strncmp(key + 2, "create", 6) == 0 && - (key[8] == '=' || key[8] == sep[0])) - parse_create(key + 8 + (key[8] == '=' ? 1 : 0)); - else if (strncmp(key + 2, "destroy", 7) == 0 && - (key[9] == '=' || key[9] == sep[0])) - parse_destroy(key + 9 + (key[9] == '=' ? 1 : 0)); - else if (strncmp(key + 2, "describe", 8) == 0 && - (key[10] == '=' || key[10] == sep[0])) { - key += 10 + (key[10] == '='); - if ((value = strchr(key, '=')) != NULL) - parse_describe(key); - else { - if (!dflag) - dodesc = 1; - break; - } - } - else - sysctlperror("unable to parse '%s'\n", key); - return; - } - - if (stale) { - purge_tree(&my_root); - stale = 0; - } - node = &my_root; - namelen = CTL_MAXNAME; - sz = sizeof(gsname); - - if (sysctlgetmibinfo(key, &name[0], &namelen, gsname, &sz, &node, - SYSCTL_VERSION) == -1) { - if (optional) - return; - sysctlparseerror(namelen, l); - EXIT(EXIT_FAILURE); - } - - type = SYSCTL_TYPE(node->sysctl_flags); - - if (value == NULL) { - if (dodesc) - dflag = 1; - print_tree(&name[0], namelen, node, type, 0, re, lastcompiled); - if (dodesc) - dflag = 0; - gsname[0] = '\0'; - return; - } - - if (fn) - trim_whitespace(value, 1); - - if (!wflag) { - sysctlperror("Must specify -w to set variables\n"); - exit(EXIT_FAILURE); - } - - canonicalize(gsname, canonname); - if (type != CTLTYPE_NODE && (w = findhandler(canonname, re, - lastcompiled)) != NULL) { - if (w->ps_w == NULL) { - sysctlperror("Cannot write `%s': %s\n", gsname, - strerror(EOPNOTSUPP)); - exit(EXIT_FAILURE); - } - (*w->ps_w)(gsname, gdname, value, name, namelen, node, type, - __UNCONST(w->ps_d)); - gsname[0] = '\0'; - return; - } - - switch (type) { - case CTLTYPE_NODE: - /* - * XXX old behavior is to print. should we error instead? - */ - print_tree(&name[0], namelen, node, CTLTYPE_NODE, 1, re, - lastcompiled); - break; - case CTLTYPE_INT: - case CTLTYPE_BOOL: - case CTLTYPE_QUAD: - write_number(&name[0], namelen, node, value); - break; - case CTLTYPE_STRING: - write_string(&name[0], namelen, node, value); - break; - case CTLTYPE_STRUCT: - /* - * XXX old behavior is to print. should we error instead? - */ - /* fprintf(warnfp, "you can't write to %s\n", gsname); */ - print_tree(&name[0], namelen, node, type, 0, re, lastcompiled); - break; - } -} - -/* - - //create=foo.bar.whatever..., - [type=(int|quad|string|struct|node),] - [size=###,] - [n=###,] - [flags=(iohxparw12),] - [addr=0x####,|symbol=...|value=...] - - size is optional for some types. type must be set before anything - else. nodes can have [rwhp], but nothing else applies. if no - size or type is given, node is asserted. writeable is the default, - with [rw] being read-only and unconditionally writeable - respectively. if you specify addr, it is assumed to be the name of - a kernel symbol, if value, CTLFLAG_OWNDATA will be asserted for - strings, CTLFLAG_IMMEDIATE for ints and u_quad_ts. you cannot - specify both value and addr. - -*/ - -static void -parse_create(char *l) -{ - struct sysctlnode node; - size_t sz; - char *nname, *key, *value, *data, *addr, *c, *t; - int name[CTL_MAXNAME], i, rc, method, flags, rw; - u_int namelen, type; - u_quad_t uq; - quad_t q; - bool b; - - if (!wflag) { - sysctlperror("Must specify -w to create nodes\n"); - exit(EXIT_FAILURE); - } - - /* - * these are the pieces that make up the description of a new - * node - */ - memset(&node, 0, sizeof(node)); - node.sysctl_num = CTL_CREATE; /* any number is fine */ - flags = 0; - rw = -1; - type = 0; - sz = 0; - data = addr = NULL; - memset(name, 0, sizeof(name)); - namelen = 0; - method = 0; - - /* - * misc stuff used when constructing - */ - i = 0; - b = false; - uq = 0; - key = NULL; - value = NULL; - - /* - * the name of the thing we're trying to create is first, so - * pick it off. - */ - nname = l; - if ((c = strchr(nname, ',')) != NULL) - *c++ = '\0'; - - while (c != NULL) { - - /* - * pull off the next "key=value" pair - */ - key = c; - if ((t = strchr(key, '=')) != NULL) { - *t++ = '\0'; - value = t; - } - else - value = NULL; - - /* - * if the "key" is "value", then that eats the rest of - * the string, so we're done, otherwise bite it off at - * the next comma. - */ - if (strcmp(key, "value") == 0) { - c = NULL; - data = value; - break; - } - else if (value) { - if ((c = strchr(value, ',')) != NULL) - *c++ = '\0'; - } - - /* - * note that we (mostly) let the invoker of prog_sysctl(8) - * play rampant here and depend on the kernel to tell - * them that they were wrong. well...within reason. - * we later check the various parameters against each - * other to make sure it makes some sort of sense. - */ - if (strcmp(key, "addr") == 0) { - /* - * we can't check these two. only the kernel - * can tell us when it fails to find the name - * (or if the address is invalid). - */ - if (method != 0) { - sysctlperror( - "%s: already have %s for new node\n", - nname, - method == CTL_CREATE ? "addr" : "symbol"); - EXIT(EXIT_FAILURE); - } - if (value == NULL) { - sysctlperror("%s: missing value\n", nname); - EXIT(EXIT_FAILURE); - } - errno = 0; - addr = (void*)strtoul(value, &t, 0); - if (t == value || *t != '\0' || errno != 0) { - sysctlperror( - "%s: '%s' is not a valid address\n", - nname, value); - EXIT(EXIT_FAILURE); - } - method = CTL_CREATE; - } - else if (strcmp(key, "symbol") == 0) { - if (method != 0) { - sysctlperror( - "%s: already have %s for new node\n", - nname, - method == CTL_CREATE ? "addr" : "symbol"); - EXIT(EXIT_FAILURE); - } - addr = value; - method = CTL_CREATESYM; - } - else if (strcmp(key, "type") == 0) { - if (value == NULL) { - sysctlperror("%s: missing value\n", nname); - EXIT(EXIT_FAILURE); - } - if (strcmp(value, "node") == 0) - type = CTLTYPE_NODE; - else if (strcmp(value, "int") == 0) { - sz = sizeof(int); - type = CTLTYPE_INT; - } - else if (strcmp(value, "bool") == 0) { - sz = sizeof(bool); - type = CTLTYPE_BOOL; - } - else if (strcmp(value, "string") == 0) - type = CTLTYPE_STRING; - else if (strcmp(value, "quad") == 0) { - sz = sizeof(u_quad_t); - type = CTLTYPE_QUAD; - } - else if (strcmp(value, "struct") == 0) - type = CTLTYPE_STRUCT; - else { - sysctlperror( - "%s: '%s' is not a valid type\n", - nname, value); - EXIT(EXIT_FAILURE); - } - } - else if (strcmp(key, "size") == 0) { - if (value == NULL) { - sysctlperror("%s: missing value\n", nname); - EXIT(EXIT_FAILURE); - } - errno = 0; - /* - * yes, i know size_t is not an unsigned long, - * but we can all agree that it ought to be, - * right? - */ - sz = strtoul(value, &t, 0); - if (t == value || *t != '\0' || errno != 0) { - sysctlperror( - "%s: '%s' is not a valid size\n", - nname, value); - EXIT(EXIT_FAILURE); - } - } - else if (strcmp(key, "n") == 0) { - if (value == NULL) { - sysctlperror("%s: missing value\n", nname); - EXIT(EXIT_FAILURE); - } - errno = 0; - q = strtoll(value, &t, 0); - if (t == value || *t != '\0' || errno != 0 || - q < INT_MIN || q > UINT_MAX) { - sysctlperror( - "%s: '%s' is not a valid mib number\n", - nname, value); - EXIT(EXIT_FAILURE); - } - node.sysctl_num = (int)q; - } - else if (strcmp(key, "flags") == 0) { - if (value == NULL) { - sysctlperror("%s: missing value\n", nname); - EXIT(EXIT_FAILURE); - } - t = value; - while (*t != '\0') { - switch (*t) { - case 'a': - flags |= CTLFLAG_ANYWRITE; - break; - case 'h': - flags |= CTLFLAG_HIDDEN; - break; - case 'i': - flags |= CTLFLAG_IMMEDIATE; - break; - case 'o': - flags |= CTLFLAG_OWNDATA; - break; - case 'p': - flags |= CTLFLAG_PRIVATE; - break; - case 'u': - flags |= CTLFLAG_UNSIGNED; - break; - case 'x': - flags |= CTLFLAG_HEX; - break; - - case 'r': - rw = CTLFLAG_READONLY; - break; - case 'w': - rw = CTLFLAG_READWRITE; - break; - default: - sysctlperror( - "%s: '%c' is not a valid flag\n", - nname, *t); - EXIT(EXIT_FAILURE); - } - t++; - } - } - else { - sysctlperror("%s: unrecognized keyword '%s'\n", - nname, key); - EXIT(EXIT_FAILURE); - } - } - - /* - * now that we've finished parsing the given string, fill in - * anything they didn't specify - */ - if (type == 0) - type = CTLTYPE_NODE; - - /* - * the "data" can be interpreted various ways depending on the - * type of node we're creating, as can the size - */ - if (data != NULL) { - if (addr != NULL) { - sysctlperror( - "%s: cannot specify both value and " - "address\n", nname); - EXIT(EXIT_FAILURE); - } - - switch (type) { - case CTLTYPE_INT: - errno = 0; - q = strtoll(data, &t, 0); - if (t == data || *t != '\0' || errno != 0 || - q < INT_MIN || q > UINT_MAX) { - sysctlperror( - "%s: '%s' is not a valid integer\n", - nname, value); - EXIT(EXIT_FAILURE); - } - i = (int)q; - if (!(flags & CTLFLAG_OWNDATA)) { - flags |= CTLFLAG_IMMEDIATE; - node.sysctl_idata = i; - } - else - node.sysctl_data = &i; - if (sz == 0) - sz = sizeof(int); - break; - case CTLTYPE_BOOL: - errno = 0; - q = strtoll(data, &t, 0); - if (t == data || *t != '\0' || errno != 0 || - (q != 0 && q != 1)) { - sysctlperror( - "%s: '%s' is not a valid bool\n", - nname, value); - EXIT(EXIT_FAILURE); - } - b = q == 1; - if (!(flags & CTLFLAG_OWNDATA)) { - flags |= CTLFLAG_IMMEDIATE; - node.sysctl_idata = b; - } - else - node.sysctl_data = &b; - if (sz == 0) - sz = sizeof(bool); - break; - case CTLTYPE_STRING: - flags |= CTLFLAG_OWNDATA; - node.sysctl_data = data; - if (sz == 0) - sz = strlen(data) + 1; - else if (sz < strlen(data) + 1) { - sysctlperror("%s: ignoring size=%zu for " - "string node, too small for given " - "value\n", nname, sz); - sz = strlen(data) + 1; - } - break; - case CTLTYPE_QUAD: - errno = 0; - uq = strtouq(data, &t, 0); - if (t == data || *t != '\0' || errno != 0) { - sysctlperror( - "%s: '%s' is not a valid quad\n", - nname, value); - EXIT(EXIT_FAILURE); - } - if (!(flags & CTLFLAG_OWNDATA)) { - flags |= CTLFLAG_IMMEDIATE; - node.sysctl_qdata = uq; - } - else - node.sysctl_data = &uq; - if (sz == 0) - sz = sizeof(u_quad_t); - break; - case CTLTYPE_STRUCT: - sysctlperror("%s: struct not initializable\n", - nname); - EXIT(EXIT_FAILURE); - } - - /* - * these methods have all provided local starting - * values that the kernel must copy in - */ - } - - /* - * hmm...no data, but we have an address of data. that's - * fine. - */ - else if (addr != 0) - node.sysctl_data = (void*)addr; - - /* - * no data and no address? well...okay. we might be able to - * manage that. - */ - else if (type != CTLTYPE_NODE) { - if (sz == 0) { - sysctlperror( - "%s: need a size or a starting value\n", - nname); - EXIT(EXIT_FAILURE); - } - if (!(flags & CTLFLAG_IMMEDIATE)) - flags |= CTLFLAG_OWNDATA; - } - - /* - * now we do a few sanity checks on the description we've - * assembled - */ - if ((flags & CTLFLAG_IMMEDIATE) && - (type == CTLTYPE_STRING || type == CTLTYPE_STRUCT)) { - sysctlperror("%s: cannot make an immediate %s\n", - nname, - (type == CTLTYPE_STRING) ? "string" : "struct"); - EXIT(EXIT_FAILURE); - } - if (type == CTLTYPE_NODE && node.sysctl_data != NULL) { - sysctlperror("%s: nodes do not have data\n", nname); - EXIT(EXIT_FAILURE); - } - - /* - * some types must have a particular size - */ - if (sz != 0) { - if ((type == CTLTYPE_INT && sz != sizeof(int)) || - (type == CTLTYPE_BOOL && sz != sizeof(bool)) || - (type == CTLTYPE_QUAD && sz != sizeof(u_quad_t)) || - (type == CTLTYPE_NODE && sz != 0)) { - sysctlperror("%s: wrong size for type\n", nname); - EXIT(EXIT_FAILURE); - } - } - else if (type == CTLTYPE_STRUCT) { - sysctlperror("%s: struct must have size\n", nname); - EXIT(EXIT_FAILURE); - } - - /* - * now...if no one said anything yet, we default nodes or - * any type that owns data being writeable, and everything - * else being readonly. - */ - if (rw == -1) { - if (type == CTLTYPE_NODE || - (flags & (CTLFLAG_OWNDATA|CTLFLAG_IMMEDIATE))) - rw = CTLFLAG_READWRITE; - else - rw = CTLFLAG_READONLY; - } - - /* - * if a kernel address was specified, that can't be made - * writeable by us. - if (rw != CTLFLAG_READONLY && addr) { - sysctlperror("%s: kernel data can only be readable\n", nname); - EXIT(EXIT_FAILURE); - } - */ - - /* - * what separator were they using in the full name of the new - * node? - */ - if ((t = strpbrk(nname, "./")) == NULL) - sep[0] = '.'; - else - sep[0] = t[0]; - sep[1] = '\0'; - - /* - * put it all together, now. t'ain't much, is it? - */ - node.sysctl_flags = SYSCTL_VERSION|flags|rw|type; - node.sysctl_size = sz; - t = strrchr(nname, sep[0]); - if (t != NULL) - strlcpy(node.sysctl_name, t + 1, sizeof(node.sysctl_name)); - else - strlcpy(node.sysctl_name, nname, sizeof(node.sysctl_name)); - if (t == nname) - t = NULL; - - /* - * if this is a new top-level node, then we don't need to find - * the mib for its parent - */ - if (t == NULL) { - namelen = 0; - gsname[0] = '\0'; - } - - /* - * on the other hand, if it's not a top-level node... - */ - else { - namelen = sizeof(name) / sizeof(name[0]); - sz = sizeof(gsname); - *t = '\0'; - rc = sysctlgetmibinfo(nname, &name[0], &namelen, - gsname, &sz, NULL, SYSCTL_VERSION); - *t = sep[0]; - if (rc == -1) { - sysctlparseerror(namelen, nname); - EXIT(EXIT_FAILURE); - } - } - - /* - * yes, a new node is being created - */ - if (method != 0) - name[namelen++] = method; - else - name[namelen++] = CTL_CREATE; - - sz = sizeof(node); - rc = prog_sysctl(&name[0], namelen, &node, &sz, &node, sizeof(node)); - - if (rc == -1) { - sysctlperror("%s: CTL_CREATE failed: %s\n", - nname, strerror(errno)); - EXIT(EXIT_FAILURE); - } - else { - if (!qflag && !nflag) - printf("%s(%s): (created)\n", nname, st(type)); - stale = 1; - } -} - -static void -parse_destroy(char *l) -{ - struct sysctlnode node; - size_t sz; - int name[CTL_MAXNAME], rc; - u_int namelen; - - if (!wflag) { - sysctlperror("Must specify -w to destroy nodes\n"); - exit(EXIT_FAILURE); - } - - memset(name, 0, sizeof(name)); - namelen = sizeof(name) / sizeof(name[0]); - sz = sizeof(gsname); - rc = sysctlgetmibinfo(l, &name[0], &namelen, gsname, &sz, NULL, - SYSCTL_VERSION); - if (rc == -1) { - sysctlparseerror(namelen, l); - EXIT(EXIT_FAILURE); - } - - memset(&node, 0, sizeof(node)); - node.sysctl_flags = SYSCTL_VERSION; - node.sysctl_num = name[namelen - 1]; - name[namelen - 1] = CTL_DESTROY; - - sz = sizeof(node); - rc = prog_sysctl(&name[0], namelen, &node, &sz, &node, sizeof(node)); - - if (rc == -1) { - sysctlperror("%s: CTL_DESTROY failed: %s\n", - l, strerror(errno)); - EXIT(EXIT_FAILURE); - } - else { - if (!qflag && !nflag) - printf("%s(%s): (destroyed)\n", gsname, - st(SYSCTL_TYPE(node.sysctl_flags))); - stale = 1; - } -} - -static void -parse_describe(char *l) -{ - struct sysctlnode newdesc; - char buf[1024], *value; - struct sysctldesc *d = (void*)&buf[0]; - int name[CTL_MAXNAME], rc; - u_int namelen; - size_t sz; - - if (!wflag) { - sysctlperror("Must specify -w to set descriptions\n"); - exit(EXIT_FAILURE); - } - - value = strchr(l, '='); - *value++ = '\0'; - - memset(name, 0, sizeof(name)); - namelen = sizeof(name) / sizeof(name[0]); - sz = sizeof(gsname); - rc = sysctlgetmibinfo(l, &name[0], &namelen, gsname, &sz, NULL, - SYSCTL_VERSION); - if (rc == -1) { - sysctlparseerror(namelen, l); - EXIT(EXIT_FAILURE); - } - - sz = sizeof(buf); - memset(&newdesc, 0, sizeof(newdesc)); - newdesc.sysctl_flags = SYSCTL_VERSION|CTLFLAG_OWNDESC; - newdesc.sysctl_num = name[namelen - 1]; - newdesc.sysctl_desc = value; - name[namelen - 1] = CTL_DESCRIBE; - rc = prog_sysctl(name, namelen, d, &sz, &newdesc, sizeof(newdesc)); - if (rc == -1) - sysctlperror("%s: CTL_DESCRIBE failed: %s\n", - gsname, strerror(errno)); - else if (d->descr_len == 1) - sysctlperror("%s: description not set\n", gsname); - else if (!qflag && !nflag) - printf("%s: %s\n", gsname, d->descr_str); -} - -/* - * ******************************************************************** - * when things go wrong... - * ******************************************************************** - */ -static void -usage(void) -{ - const char *progname = getprogname(); - - (void)fprintf(stderr, - "usage:\t%s %s\n" - "\t%s %s\n" - "\t%s %s\n" - "\t%s %s\n" - "\t%s %s\n" - "\t%s %s\n", - progname, "[-dneq] [-x[x]|-r] variable ...", - progname, "[-ne] [-q] -w variable=value ...", - progname, "[-dne] -a", - progname, "[-dne] -A", - progname, "[-ne] -M", - progname, "[-dne] [-q] -f file"); - exit(EXIT_FAILURE); -} - -static void -getdesc1(int *name, u_int namelen, struct sysctlnode *pnode) -{ - struct sysctlnode node; - char buf[1024], *desc; - struct sysctldesc *d = (void*)buf; - size_t sz = sizeof(buf); - int rc; - - memset(&node, 0, sizeof(node)); - node.sysctl_flags = SYSCTL_VERSION; - node.sysctl_num = name[namelen - 1]; - name[namelen - 1] = CTL_DESCRIBE; - rc = prog_sysctl(name, namelen, d, &sz, &node, sizeof(node)); - - if (rc == -1 || - d->descr_len == 1 || - d->descr_num != pnode->sysctl_num || - d->descr_ver != pnode->sysctl_ver) - desc = (char *)-1; - else - desc = malloc(d->descr_len); - - if (desc == NULL) - desc = (char *)-1; - if (desc != (char *)-1) - memcpy(desc, &d->descr_str[0], d->descr_len); - name[namelen - 1] = node.sysctl_num; - if (pnode->sysctl_desc != NULL && - pnode->sysctl_desc != (const char *)-1) - free(__UNCONST(pnode->sysctl_desc)); - pnode->sysctl_desc = desc; -} - -static void -getdesc(int *name, u_int namelen, struct sysctlnode *pnode) -{ - struct sysctlnode *node = pnode->sysctl_child; - struct sysctldesc *d, *p, *plim; - char *desc; - size_t i, sz, child_cnt; - int rc; - - sz = 128 * pnode->sysctl_clen; - name[namelen] = CTL_DESCRIBE; - - /* - * attempt *twice* to get the description chunk. if two tries - * doesn't work, give up. - */ - i = 0; - do { - d = malloc(sz); - if (d == NULL) - return; - rc = prog_sysctl(name, namelen + 1, d, &sz, NULL, 0); - if (rc == -1) { - free(d); - d = NULL; - if (i == 0 && errno == ENOMEM) - i = 1; - else - return; - } - } while (d == NULL); - - /* - * hokey nested loop here, giving O(n**2) behavior, but should - * suffice for now - */ - plim = /*LINTED ptr cast*/(struct sysctldesc *)((char*)d + sz); - child_cnt = (pnode->sysctl_flags & CTLTYPE_NODE) ? pnode->sysctl_clen - : 0; - for (i = 0; i < child_cnt; i++) { - node = &pnode->sysctl_child[i]; - for (p = d; p < plim; p = NEXT_DESCR(p)) - if (node->sysctl_num == p->descr_num) - break; - if (p < plim && node->sysctl_ver == p->descr_ver) { - /* - * match found, attempt to attach description - */ - if (p->descr_len == 1) - desc = NULL; - else - desc = malloc(p->descr_len); - if (desc == NULL) - desc = (char *)-1; - else - memcpy(desc, &p->descr_str[0], p->descr_len); - node->sysctl_desc = desc; - } - } - - free(d); -} - -static void -trim_whitespace(char *s, int dir) -{ - char *i, *o; - - i = o = s; - if (dir & 1) - while (isspace((unsigned char)*i)) - i++; - while ((*o++ = *i++) != '\0'); - o -= 2; /* already past nul, skip back to before it */ - if (dir & 2) - while (o > s && isspace((unsigned char)*o)) - *o-- = '\0'; -} - -void -sysctlerror(int soft) -{ - if (soft) { - switch (errno) { - case ENOENT: - case ENOPROTOOPT: - case ENOTDIR: - case EINVAL: - case EOPNOTSUPP: - case EPROTONOSUPPORT: - if (Aflag || req) - sysctlperror("%s: the value is not available " - "(%s)\n", gsname, strerror(errno)); - return; - } - } - - if (Aflag || req) - sysctlperror("%s: %s\n", gsname, strerror(errno)); - if (!soft) - EXIT(EXIT_FAILURE); -} - -void -sysctlparseerror(u_int namelen, const char *pname) -{ - - if (qflag) { - errs++; - return; - } - sysctlperror("%s level name '%s' in '%s' is invalid\n", - lname[namelen], gsname, pname); -} - -static void -sysctlperror(const char *fmt, ...) -{ - va_list ap; - - (void)fprintf(warnfp, "%s: ", getprogname()); - if (fn) - (void)fprintf(warnfp, "%s#%zu: ", fn, nr); - va_start(ap, fmt); - (void)vfprintf(warnfp, fmt, ap); - va_end(ap); - errs++; -} - - -/* - * ******************************************************************** - * how to write to a "simple" node - * ******************************************************************** - */ -static void -write_number(int *name, u_int namelen, struct sysctlnode *node, char *value) -{ - u_int ii, io; - u_quad_t qi, qo; - size_t si, so; - bool bi, bo; - int rc; - void *i, *o; - char *t; - - if (fn) - trim_whitespace(value, 3); - - si = so = 0; - i = o = NULL; - bi = bo = false; - errno = 0; - qi = strtouq(value, &t, 0); - if (qi == UQUAD_MAX && errno == ERANGE) { - sysctlperror("%s: %s\n", value, strerror(errno)); - EXIT(EXIT_FAILURE); - } - if (t == value || *t != '\0') { - sysctlperror("%s: not a number\n", value); - EXIT(EXIT_FAILURE); - } - - switch (SYSCTL_TYPE(node->sysctl_flags)) { - case CTLTYPE_INT: - ii = (u_int)qi; - io = (u_int)(qi >> 32); - if (io != (u_int)-1 && io != 0) { - sysctlperror("%s: %s\n", value, strerror(ERANGE)); - EXIT(EXIT_FAILURE); - } - o = &io; - so = sizeof(io); - i = ⅈ - si = sizeof(ii); - break; - case CTLTYPE_BOOL: - bi = (bool)qi; - o = &bo; - so = sizeof(bo); - i = &bi; - si = sizeof(bi); - break; - case CTLTYPE_QUAD: - o = &qo; - so = sizeof(qo); - i = &qi; - si = sizeof(qi); - break; - } - - rc = prog_sysctl(name, namelen, o, &so, i, si); - if (rc == -1) { - sysctlerror(0); - return; - } - - switch (SYSCTL_TYPE(node->sysctl_flags)) { - case CTLTYPE_INT: - display_number(node, gsname, &io, sizeof(io), DISPLAY_OLD); - display_number(node, gsname, &ii, sizeof(ii), DISPLAY_NEW); - break; - case CTLTYPE_BOOL: - display_number(node, gsname, &bo, sizeof(bo), DISPLAY_OLD); - display_number(node, gsname, &bi, sizeof(bi), DISPLAY_NEW); - break; - case CTLTYPE_QUAD: - display_number(node, gsname, &qo, sizeof(qo), DISPLAY_OLD); - display_number(node, gsname, &qi, sizeof(qi), DISPLAY_NEW); - break; - } -} - -static void -write_string(int *name, u_int namelen, struct sysctlnode *node, char *value) -{ - char *i, *o; - size_t si, so; - int rc; - - i = value; - si = strlen(i) + 1; - so = node->sysctl_size; - if (si > so && so != 0) { - sysctlperror("%s: string too long\n", value); - EXIT(EXIT_FAILURE); - } - o = malloc(so); - if (o == NULL) { - sysctlperror("%s: !malloc failed!\n", gsname); - exit(EXIT_FAILURE); - } - - rc = prog_sysctl(name, namelen, o, &so, i, si); - if (rc == -1) { - sysctlerror(0); - return; - } - - display_string(node, gsname, o, so, DISPLAY_OLD); - display_string(node, gsname, i, si, DISPLAY_NEW); - free(o); -} - -/* - * ******************************************************************** - * simple ways to print stuff consistently - * ******************************************************************** - */ -static void -display_number(const struct sysctlnode *node, const char *name, - const void *data, size_t sz, int n) -{ - u_quad_t q; - bool b; - int i; - - if (qflag) - return; - if ((nflag || rflag) && (n == DISPLAY_OLD)) - return; - - if (rflag && n != DISPLAY_OLD) { - fwrite(data, sz, 1, stdout); - return; - } - - if (!nflag) { - if (n == DISPLAY_VALUE) - printf("%s%s", name, eq); - else if (n == DISPLAY_OLD) - printf("%s: ", name); - } - - if (xflag > 1) { - if (n != DISPLAY_NEW) - printf("\n"); - hex_dump(data, sz); - return; - } - - switch (SYSCTL_TYPE(node->sysctl_flags)) { - case CTLTYPE_INT: - memcpy(&i, data, sz); - if (xflag) - printf("0x%0*x", (int)sz * 2, i); - else if (node->sysctl_flags & CTLFLAG_HEX) - printf("%#x", i); - else if (node->sysctl_flags & CTLFLAG_UNSIGNED) - printf("%u", i); - else - printf("%d", i); - break; - case CTLTYPE_BOOL: - memcpy(&b, data, sz); - if (xflag) - printf("0x%0*x", (int)sz * 2, b); - else if (node->sysctl_flags & CTLFLAG_HEX) - printf("%#x", b); - else - printf("%d", b); - break; - case CTLTYPE_QUAD: - memcpy(&q, data, sz); - if (xflag) - printf("0x%0*" PRIx64, (int)sz * 2, q); - else if (node->sysctl_flags & CTLFLAG_HEX) - printf("%#" PRIx64, q); - else if (node->sysctl_flags & CTLFLAG_UNSIGNED) - printf("%" PRIu64, q); - else - printf("%" PRIu64, q); - break; - } - - if (n == DISPLAY_OLD) - printf(" -> "); - else - printf("\n"); -} - -static void -display_string(const struct sysctlnode *node, const char *name, - const void *data, size_t sz, int n) -{ - const unsigned char *buf = data; - int ni; - - if (qflag) - return; - if ((nflag || rflag) && (n == DISPLAY_OLD)) - return; - - if (rflag && n != DISPLAY_OLD) { - fwrite(data, sz, 1, stdout); - return; - } - - if (!nflag) { - if (n == DISPLAY_VALUE) - printf("%s%s", name, eq); - else if (n == DISPLAY_OLD) - printf("%s: ", name); - } - - if (xflag > 1) { - if (n != DISPLAY_NEW) - printf("\n"); - hex_dump(data, sz); - return; - } - - if (xflag || node->sysctl_flags & CTLFLAG_HEX) { - for (ni = 0; ni < (int)sz; ni++) { - if (xflag) - printf("%02x", buf[ni]); - if (buf[ni] == '\0') - break; - if (!xflag) - printf("\\x%2.2x", buf[ni]); - } - } - else - printf("%.*s", (int)sz, buf); - - if (n == DISPLAY_OLD) - printf(" -> "); - else - printf("\n"); -} - -/*ARGSUSED*/ -static void -display_struct(const struct sysctlnode *node, const char *name, - const void *data, size_t sz, int n) -{ - const unsigned char *buf = data; - int ni; - size_t more; - - if (qflag) - return; - if (!(xflag || rflag)) { - if (Aflag || req) - sysctlperror( - "%s: this type is unknown to this program\n", - gsname); - return; - } - if ((nflag || rflag) && (n == DISPLAY_OLD)) - return; - - if (rflag && n != DISPLAY_OLD) { - fwrite(data, sz, 1, stdout); - return; - } - - if (!nflag) { - if (n == DISPLAY_VALUE) - printf("%s%s", name, eq); - else if (n == DISPLAY_OLD) - printf("%s: ", name); - } - - if (xflag > 1) { - if (n != DISPLAY_NEW) - printf("\n"); - hex_dump(data, sz); - return; - } - - if (sz > 16) { - more = sz - 16; - sz = 16; - } - else - more = 0; - for (ni = 0; ni < (int)sz; ni++) - printf("%02x", buf[ni]); - if (more) - printf("...(%zu more bytes)", more); - printf("\n"); -} - -static void -hex_dump(const unsigned char *buf, size_t len) -{ - unsigned int i; - int j; - char line[80], tmp[12]; - - memset(line, ' ', sizeof(line)); - for (i = 0, j = 15; i < len; i++) { - j = i % 16; - /* reset line */ - if (j == 0) { - line[58] = '|'; - line[77] = '|'; - line[78] = 0; - snprintf(tmp, sizeof(tmp), "%07x", i); - memcpy(&line[0], tmp, 7); - } - /* copy out hex version of byte */ - snprintf(tmp, sizeof(tmp), "%02x", buf[i]); - memcpy(&line[9 + j * 3], tmp, 2); - /* copy out plain version of byte */ - line[60 + j] = (isprint(buf[i])) ? buf[i] : '.'; - /* print a full line and erase it */ - if (j == 15) { - printf("%s\n", line); - memset(line, ' ', sizeof(line)); - } - } - if (line[0] != ' ') - printf("%s\n", line); - printf("%07zu bytes\n", len); -} - -/* - * ******************************************************************** - * functions that handle particular nodes - * ******************************************************************** - */ -/*ARGSUSED*/ -static void -printother(HANDLER_ARGS) -{ - int rc; - void *p; - size_t sz1, sz2; - - if (!(Aflag || req) || Mflag) - return; - - /* - * okay...you asked for it, so let's give it a go - */ - while (type != CTLTYPE_NODE && (xflag || rflag)) { - rc = prog_sysctl(name, namelen, NULL, &sz1, NULL, 0); - if (rc == -1 || sz1 == 0) - break; - p = malloc(sz1); - if (p == NULL) - break; - sz2 = sz1; - rc = prog_sysctl(name, namelen, p, &sz2, NULL, 0); - if (rc == -1 || sz1 != sz2) { - free(p); - break; - } - display_struct(pnode, gsname, p, sz1, DISPLAY_VALUE); - free(p); - return; - } - - /* - * that didn't work...do we have a specific message for this - * thing? - */ - if (v != NULL) { - sysctlperror("%s: use '%s' to view this information\n", - gsname, (const char *)v); - return; - } - - /* - * hmm...i wonder if we have any generic hints? - */ - switch (name[0]) { - case CTL_NET: - sysctlperror("%s: use 'netstat' to view this information\n", - sname); - break; - case CTL_DEBUG: - sysctlperror("%s: missing 'options DEBUG' from kernel?\n", - sname); - break; - case CTL_DDB: - sysctlperror("%s: missing 'options DDB' from kernel?\n", - sname); - break; - case CTL_VENDOR: - sysctlperror("%s: no vendor extensions installed\n", - sname); - break; - } -} - -/*ARGSUSED*/ -static void -kern_clockrate(HANDLER_ARGS) -{ - struct clockinfo clkinfo; - size_t sz; - int rc; - - sz = sizeof(clkinfo); - rc = prog_sysctl(name, namelen, &clkinfo, &sz, NULL, 0); - if (rc == -1) { - sysctlerror(1); - return; - } - if (sz != sizeof(clkinfo)) - errx(EXIT_FAILURE, "%s: !returned size wrong!", sname); - - if (xflag || rflag) { - display_struct(pnode, sname, &clkinfo, sz, - DISPLAY_VALUE); - return; - } - else if (!nflag) - printf("%s: ", sname); - printf("tick = %d, tickadj = %d, hz = %d, profhz = %d, stathz = %d\n", - clkinfo.tick, clkinfo.tickadj, - clkinfo.hz, clkinfo.profhz, clkinfo.stathz); -} - -/*ARGSUSED*/ -static void -kern_boottime(HANDLER_ARGS) -{ - struct timeval timeval; - time_t boottime; - size_t sz; - int rc; - - sz = sizeof(timeval); - rc = prog_sysctl(name, namelen, &timeval, &sz, NULL, 0); - if (rc == -1) { - sysctlerror(1); - return; - } - if (sz != sizeof(timeval)) - errx(EXIT_FAILURE, "%s: !returned size wrong!", sname); - - boottime = timeval.tv_sec; - if (xflag || rflag) - display_struct(pnode, sname, &timeval, sz, - DISPLAY_VALUE); - else if (!nflag) - /* ctime() provides the \n */ - printf("%s%s%s", sname, eq, ctime(&boottime)); - else if (nflag == 1) - printf("%ld\n", (long)boottime); - else - printf("%ld.%06ld\n", (long)timeval.tv_sec, - (long)timeval.tv_usec); -} - -/*ARGSUSED*/ -static void -kern_consdev(HANDLER_ARGS) -{ - dev_t cons; - size_t sz; - int rc; - - sz = sizeof(cons); - rc = prog_sysctl(name, namelen, &cons, &sz, NULL, 0); - if (rc == -1) { - sysctlerror(1); - return; - } - if (sz != sizeof(cons)) - errx(EXIT_FAILURE, "%s: !returned size wrong!", sname); - - if (xflag || rflag) - display_struct(pnode, sname, &cons, sz, - DISPLAY_VALUE); - else { - if (!nflag) - printf("%s%s", sname, eq); - if (nflag < 2 && (sname = devname(cons, S_IFCHR)) != NULL) - printf("%s\n", sname); - else - printf("0x%llx\n", (unsigned long long)cons); - } -} - -/*ARGSUSED*/ -static void -kern_cp_time(HANDLER_ARGS) -{ - u_int64_t *cp_time; - size_t sz, osz; - int rc, i, n; - char s[sizeof("kern.cp_time.nnnnnn")]; - const char *tname; - - /* - * three things to do here. - * case 1: get sum (no Aflag and namelen == 2) - * case 2: get specific processor (namelen == 3) - * case 3: get all processors (Aflag and namelen == 2) - */ - - if (namelen == 2 && Aflag) { - sz = sizeof(n); - rc = sysctlbyname("hw.ncpu", &n, &sz, NULL, 0); - if (rc != 0) - return; /* XXX print an error, eh? */ - n++; /* Add on space for the sum. */ - sz = n * sizeof(u_int64_t) * CPUSTATES; - } - else { - n = -1; /* Just print one data set. */ - sz = sizeof(u_int64_t) * CPUSTATES; - } - - cp_time = malloc(sz); - if (cp_time == NULL) { - sysctlerror(1); - return; - } - - osz = sz; - rc = prog_sysctl(name, namelen, cp_time + (n != -1) * CPUSTATES, &osz, - NULL, 0); - - if (rc == -1) { - sysctlerror(1); - free(cp_time); - return; - } - - /* - * Check, but account for space we'll occupy with the sum. - */ - if (osz != sz - (n != -1) * CPUSTATES * sizeof(u_int64_t)) - errx(EXIT_FAILURE, "%s: !returned size wrong!", sname); - - /* - * Compute the actual sum. Two calls would be easier (we - * could just call ourselves recursively above), but the - * numbers wouldn't add up. - */ - if (n != -1) { - memset(cp_time, 0, sizeof(u_int64_t) * CPUSTATES); - for (i = 1; i < n; i++) { - cp_time[CP_USER] += cp_time[i * CPUSTATES + CP_USER]; - cp_time[CP_NICE] += cp_time[i * CPUSTATES + CP_NICE]; - cp_time[CP_SYS] += cp_time[i * CPUSTATES + CP_SYS]; - cp_time[CP_INTR] += cp_time[i * CPUSTATES + CP_INTR]; - cp_time[CP_IDLE] += cp_time[i * CPUSTATES + CP_IDLE]; - } - } - - tname = sname; - for (i = 0; n == -1 || i < n; i++) { - if (i > 0) { - (void)snprintf(s, sizeof(s), "%s%s%d", sname, sep, - i - 1); - tname = s; - } - if (xflag || rflag) - display_struct(pnode, tname, cp_time + (i * CPUSTATES), - sizeof(u_int64_t) * CPUSTATES, - DISPLAY_VALUE); - else { - if (!nflag) - printf("%s: ", tname); - printf("user = %" PRIu64 - ", nice = %" PRIu64 - ", sys = %" PRIu64 - ", intr = %" PRIu64 - ", idle = %" PRIu64 - "\n", - cp_time[i * CPUSTATES + CP_USER], - cp_time[i * CPUSTATES + CP_NICE], - cp_time[i * CPUSTATES + CP_SYS], - cp_time[i * CPUSTATES + CP_INTR], - cp_time[i * CPUSTATES + CP_IDLE]); - } - /* - * Just printing the one node. - */ - if (n == -1) - break; - } - - free(cp_time); -} - -/*ARGSUSED*/ -static void -kern_drivers(HANDLER_ARGS) -{ - struct kinfo_drivers *kd; - size_t sz, i; - int rc; - const char *comma; - - rc = prog_sysctl(name, namelen, NULL, &sz, NULL, 0); - if (rc == -1) { - sysctlerror(1); - return; - } - - if (sz % sizeof(*kd)) - err(EXIT_FAILURE, "bad size %zu for kern.drivers", sz); - - kd = malloc(sz); - if (kd == NULL) { - sysctlerror(1); - return; - } - - rc = prog_sysctl(name, namelen, kd, &sz, NULL, 0); - if (rc == -1) { - sysctlerror(1); - free(kd); - return; - } - - comma = ""; - if (!nflag) - printf("%s%s", sname, eq); - for (i = 0, sz /= sizeof(*kd); i < sz; i++) { - (void)printf("%s[%d %d %s]", comma, kd[i].d_cmajor, - kd[i].d_bmajor, kd[i].d_name); - comma = ", "; - } - (void)printf("\n"); - free(kd); -} - -/*ARGSUSED*/ -static void -kern_cp_id(HANDLER_ARGS) -{ - u_int64_t *cp_id; - size_t sz, osz; - int rc, i, n; - char s[sizeof("kern.cp_id.nnnnnn")]; - const char *tname; - struct sysctlnode node = *pnode; - - /* - * three things to do here. - * case 1: print a specific cpu id (namelen == 3) - * case 2: print all cpu ids separately (Aflag set) - * case 3: print all cpu ids on one line - */ - - if (namelen == 2) { - sz = sizeof(n); - rc = sysctlbyname("hw.ncpu", &n, &sz, NULL, 0); - if (rc != 0) - return; /* XXX print an error, eh? */ - sz = n * sizeof(u_int64_t); - } - else { - n = -1; /* Just print one cpu id. */ - sz = sizeof(u_int64_t); - } - - cp_id = malloc(sz); - if (cp_id == NULL) { - sysctlerror(1); - return; - } - - osz = sz; - rc = prog_sysctl(name, namelen, cp_id, &osz, NULL, 0); - if (rc == -1) { - sysctlerror(1); - free(cp_id); - return; - } - - /* - * Check that we got back what we asked for. - */ - if (osz != sz) - errx(EXIT_FAILURE, "%s: !returned size wrong!", sname); - - /* pretend for output purposes */ - node.sysctl_flags = SYSCTL_FLAGS(pnode->sysctl_flags) | - SYSCTL_TYPE(CTLTYPE_QUAD); - - tname = sname; - if (namelen == 3) - display_number(&node, tname, cp_id, - sizeof(u_int64_t), - DISPLAY_VALUE); - else if (Aflag) { - for (i = 0; i < n; i++) - (void)snprintf(s, sizeof(s), "%s%s%d", sname, sep, i); - tname = s; - display_number(&node, tname, &cp_id[i], - sizeof(u_int64_t), - DISPLAY_VALUE); - } - else { - if (xflag || rflag) - display_struct(pnode, tname, cp_id, sz, DISPLAY_VALUE); - else { - if (!nflag) - printf("%s: ", tname); - for (i = 0; i < n; i++) { - if (i) - printf(", "); - printf("%d = %" PRIu64, i, cp_id[i]); - } - printf("\n"); - } - } - - free(cp_id); -} - -/*ARGSUSED*/ -static void -vm_loadavg(HANDLER_ARGS) -{ - struct loadavg loadavg; - size_t sz; - int rc; - - sz = sizeof(loadavg); - rc = prog_sysctl(name, namelen, &loadavg, &sz, NULL, 0); - if (rc == -1) { - sysctlerror(1); - return; - } - if (sz != sizeof(loadavg)) - errx(EXIT_FAILURE, "%s: !returned size wrong!", sname); - - if (xflag || rflag) { - display_struct(pnode, sname, &loadavg, sz, - DISPLAY_VALUE); - return; - } - if (!nflag) - printf("%s: ", sname); - printf("%.2f %.2f %.2f\n", - (double) loadavg.ldavg[0] / loadavg.fscale, - (double) loadavg.ldavg[1] / loadavg.fscale, - (double) loadavg.ldavg[2] / loadavg.fscale); -} - -/*ARGSUSED*/ -static void -proc_limit(HANDLER_ARGS) -{ - u_quad_t olim, *newp, nlim; - size_t osz, nsz; - char *t; - int rc; - - if (fn) - trim_whitespace(value, 3); - - osz = sizeof(olim); - if (value != NULL) { - nsz = sizeof(nlim); - newp = &nlim; - if (strcmp(value, "unlimited") == 0) - nlim = RLIM_INFINITY; - else { - errno = 0; - nlim = strtouq(value, &t, 0); - if (t == value || *t != '\0' || errno != 0) { - sysctlperror("%s: '%s' is not a valid limit\n", - sname, value); - EXIT(EXIT_FAILURE); - } - } - } - else { - nsz = 0; - newp = NULL; - } - - rc = prog_sysctl(name, namelen, &olim, &osz, newp, nsz); - if (rc == -1) { - sysctlerror(newp == NULL); - return; - } - - if (newp && qflag) - return; - - if (rflag || xflag || olim != RLIM_INFINITY) - display_number(pnode, sname, &olim, sizeof(olim), - newp ? DISPLAY_OLD : DISPLAY_VALUE); - else - display_string(pnode, sname, "unlimited", 10, - newp ? DISPLAY_OLD : DISPLAY_VALUE); - - if (newp) { - if (rflag || xflag || nlim != RLIM_INFINITY) - display_number(pnode, sname, &nlim, sizeof(nlim), - DISPLAY_NEW); - else - display_string(pnode, sname, "unlimited", 10, - DISPLAY_NEW); - } -} - -#ifdef CPU_DISKINFO -/*ARGSUSED*/ -static void -machdep_diskinfo(HANDLER_ARGS) -{ - struct disklist *dl; - struct biosdisk_info *bi; - struct nativedisk_info *ni; - int rc; - size_t sz; - uint i, b, lim; - - rc = prog_sysctl(name, namelen, NULL, &sz, NULL, 0); - if (rc == -1) { - sysctlerror(1); - return; - } - dl = malloc(sz); - if (dl == NULL) { - sysctlerror(1); - return; - } - rc = prog_sysctl(name, namelen, dl, &sz, NULL, 0); - if (rc == -1) { - sysctlerror(1); - return; - } - - if (!nflag) - printf("%s: ", sname); - lim = dl->dl_nbiosdisks; - if (lim > MAX_BIOSDISKS) - lim = MAX_BIOSDISKS; - for (bi = dl->dl_biosdisks, i = 0; i < lim; bi++, i++) - printf("%x:%" PRIu64 "(%d/%d/%d),%x ", - bi->bi_dev, bi->bi_lbasecs, - bi->bi_cyl, bi->bi_head, bi->bi_sec, - bi->bi_flags); - lim = dl->dl_nnativedisks; - ni = dl->dl_nativedisks; - bi = dl->dl_biosdisks; - /* LINTED -- pointer casts are tedious */ - if ((char *)&ni[lim] != (char *)dl + sz) { - sysctlperror("%s: size mismatch\n", gsname); - return; - } - for (i = 0; i < lim; ni++, i++) { - char t = ':'; - printf(" %.*s", (int)sizeof ni->ni_devname, - ni->ni_devname); - for (b = 0; b < (unsigned int)ni->ni_nmatches; t = ',', b++) - printf("%c%x", t, - bi[ni->ni_biosmatches[b]].bi_dev); - } - printf("\n"); - free(dl); -} -#endif /* CPU_DISKINFO */ - -/*ARGSUSED*/ -static void -mode_bits(HANDLER_ARGS) -{ - char buf[12], outbuf[100]; - int o, m, *newp, rc; - size_t osz, nsz; - mode_t om, mm; - - if (fn) - trim_whitespace(value, 3); - - newp = NULL; - osz = sizeof(o); - if (value != NULL) { - void *foo; - int tt; - size_t ttsz = sizeof(tt); - mode_t old_umask; - - nsz = sizeof(m); - newp = &m; - errno = 0; - rc = prog_sysctl(name, namelen, &tt, &ttsz, NULL, 0); - if (rc == -1) { - sysctlperror("%s: failed query\n", sname); - return; - } - - old_umask = umask(0); - foo = setmode(value); - umask(old_umask); - if (foo == NULL) { - sysctlperror("%s: '%s' is an invalid mode\n", sname, - value); - EXIT(EXIT_FAILURE); - } - old_umask = umask(0); - m = getmode(foo, (mode_t)tt); - umask(old_umask); - if (errno) { - sysctlperror("%s: '%s' is an invalid mode\n", sname, - value); - EXIT(EXIT_FAILURE); - } - } - else { - nsz = 0; - newp = NULL; - } - - rc = prog_sysctl(name, namelen, &o, &osz, newp, nsz); - if (rc == -1) { - sysctlerror(newp == NULL); - return; - } - - if (newp && qflag) - return; - - om = (mode_t)o; - mm = (mode_t)m; - - if (rflag || xflag) - display_number(pnode, sname, &o, sizeof(o), - newp ? DISPLAY_OLD : DISPLAY_VALUE); - else { - memset(buf, 0, sizeof(buf)); - strmode(om, buf); - rc = snprintf(outbuf, sizeof(outbuf), "%04o (%s)", om, buf + 1); - display_string(pnode, sname, outbuf, rc, newp ? DISPLAY_OLD : DISPLAY_VALUE); - } - - if (newp) { - if (rflag || xflag) - display_number(pnode, sname, &m, sizeof(m), - DISPLAY_NEW); - else { - memset(buf, 0, sizeof(buf)); - strmode(mm, buf); - rc = snprintf(outbuf, sizeof(outbuf), "%04o (%s)", mm, buf + 1); - display_string(pnode, sname, outbuf, rc, DISPLAY_NEW); - } - } -} - -typedef __BITMAP_TYPE(, uint32_t, 0x10000) bitmap; - -static char * -bitmask_print(const bitmap *o) -{ - char *s, *os; - - s = os = NULL; - for (size_t i = 0; i < MAXPORTS; i++) - if (__BITMAP_ISSET(i, o)) { - int rv; - - if (os) - rv = asprintf(&s, "%s,%zu", os, i); - else - rv = asprintf(&s, "%zu", i); - if (rv == -1) - err(EXIT_FAILURE, "%s 1", __func__); - free(os); - os = s; - } - if (s == NULL && (s = strdup("")) == NULL) - err(EXIT_FAILURE, "%s 2", __func__); - return s; -} - -static void -bitmask_scan(const void *v, bitmap *o) -{ - char *s = strdup(v); - if (s == NULL) - err(EXIT_FAILURE, "%s", __func__); - - __BITMAP_ZERO(o); - for (s = strtok(s, ","); s; s = strtok(NULL, ",")) { - char *e; - errno = 0; - unsigned long l = strtoul(s, &e, 0); - if ((l == ULONG_MAX && errno == ERANGE) || s == e || *e) - errx(EXIT_FAILURE, "Invalid port: %s", s); - if (l >= MAXPORTS) - errx(EXIT_FAILURE, "Port out of range: %s", s); - __BITMAP_SET(l, o); - } -} - - -static void -reserve(HANDLER_ARGS) -{ - int rc; - size_t osz, nsz; - bitmap o, n; - - if (fn) - trim_whitespace(value, 3); - - osz = sizeof(o); - if (value) { - bitmask_scan(value, &n); - value = (char *)&n; - nsz = sizeof(n); - } else - nsz = 0; - - rc = prog_sysctl(name, namelen, &o, &osz, value, nsz); - if (rc == -1) { - sysctlerror(value == NULL); - return; - } - - if (value && qflag) - return; - - if (rflag || xflag) - display_struct(pnode, sname, &o, sizeof(o), - value ? DISPLAY_OLD : DISPLAY_VALUE); - else { - char *s = bitmask_print(&o); - display_string(pnode, sname, s, strlen(s), - value ? DISPLAY_OLD : DISPLAY_VALUE); - free(s); - } - - if (value) { - if (rflag || xflag) - display_struct(pnode, sname, &n, sizeof(n), - DISPLAY_NEW); - else { - char *s = bitmask_print(&n); - display_string(pnode, sname, s, strlen(s), DISPLAY_NEW); - free(s); - } - } -} diff --git a/sbin/sysctl/sysctl_hostops.c b/sbin/sysctl/sysctl_hostops.c deleted file mode 100644 index 9f1b25a24..000000000 --- a/sbin/sysctl/sysctl_hostops.c +++ /dev/null @@ -1,41 +0,0 @@ -/* $NetBSD: sysctl_hostops.c,v 1.1 2010/12/13 17:47:40 pooka Exp $ */ - -/* - * Copyright (c) 2010 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifndef lint -__RCSID("$NetBSD: sysctl_hostops.c,v 1.1 2010/12/13 17:47:40 pooka Exp $"); -#endif /* !lint */ - -#include -#include - -#include "prog_ops.h" - -const struct prog_ops prog_ops = { - .op_sysctl = sysctl, -}; diff --git a/sbin/sysctl/sysctl_rumpops.c b/sbin/sysctl/sysctl_rumpops.c deleted file mode 100644 index c00b67b4f..000000000 --- a/sbin/sysctl/sysctl_rumpops.c +++ /dev/null @@ -1,47 +0,0 @@ -/* $NetBSD: sysctl_rumpops.c,v 1.1 2010/12/13 17:47:40 pooka Exp $ */ - -/* - * Copyright (c) 2010 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#ifndef lint -__RCSID("$NetBSD: sysctl_rumpops.c,v 1.1 2010/12/13 17:47:40 pooka Exp $"); -#endif /* !lint */ - -#include -#include - -#include -#include -#include - -#include "prog_ops.h" - -const struct prog_ops prog_ops = { - .op_init = rumpclient_init, - - .op_sysctl = rump_sys___sysctl, -};