Remove NetBSD related files
This commit is contained in:
parent
328174370e
commit
2d7141ec30
|
|
@ -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 <bsd.own.mk>
|
||||
|
||||
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 <bsd.subdir.mk>
|
||||
|
|
@ -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 <bsd.own.mk> # for MKDYNAMICROOT definition
|
||||
|
||||
WARNS?= 5
|
||||
BINDIR?= /sbin
|
||||
|
||||
.if (${MKDYNAMICROOT} == "no")
|
||||
LDSTATIC?= -static
|
||||
.endif
|
||||
|
|
@ -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
|
||||
|
|
@ -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 <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: af_atalk.c,v 1.19 2013/10/19 00:35:30 christos Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <netatalk/at.h>
|
||||
|
||||
#include <netdb.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <util.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
|
@ -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 <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: af_inet.c,v 1.17 2015/05/12 14:05:29 roy Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <util.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
|
@ -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 <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: af_inet6.c,v 1.33 2015/05/12 14:05:29 roy Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet6/nd6.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <util.h>
|
||||
|
||||
#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]);
|
||||
}
|
||||
|
|
@ -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 <sys/types.h>
|
||||
#include <prop/proplib.h>
|
||||
|
||||
#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 */
|
||||
|
|
@ -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 <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: af_link.c,v 1.7 2014/01/19 22:31:13 matt Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <util.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
|
@ -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 <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: env.c,v 1.9 2013/02/07 13:20:51 apb Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <util.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
|
@ -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 <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: ether.c,v 1.2 2012/11/01 13:43:23 pgoyette Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_ether.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <util.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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 <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: ifconfig_hostops.c,v 1.1 2010/12/13 17:35:08 pooka Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "prog_ops.h"
|
||||
|
||||
const struct prog_ops prog_ops = {
|
||||
.op_socket = socket,
|
||||
.op_ioctl = ioctl,
|
||||
.op_read = read,
|
||||
.op_close = close,
|
||||
};
|
||||
|
|
@ -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 <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: ifconfig_rumpops.c,v 1.1 2010/12/13 17:35:08 pooka Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rump/rump.h>
|
||||
#include <rump/rump_syscalls.h>
|
||||
#include <rump/rumpclient.h>
|
||||
|
||||
#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,
|
||||
};
|
||||
|
|
@ -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 <prop/proplib.h>
|
||||
|
||||
#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 */
|
||||
|
|
@ -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 <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: parse.c,v 1.18 2013/07/17 15:42:03 christos Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <netdb.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/param.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <netatalk/at.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
|
@ -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 <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: pfsync.c,v 1.1 2009/09/14 10:36:49 degroote Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
#include <net/pfvar.h>
|
||||
#include <net/if_pfsync.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <util.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
|
@ -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 <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: tunnel.c,v 1.20 2013/10/19 15:59:15 christos Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#ifdef INET6
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <util.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
|
@ -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 <bsd.prog.mk>
|
||||
119
sbin/init/NOTES
119
sbin/init/NOTES
|
|
@ -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
|
||||
390
sbin/init/init.8
390
sbin/init/init.8
|
|
@ -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 .
|
||||
1902
sbin/init/init.c
1902
sbin/init/init.c
File diff suppressed because it is too large
Load Diff
|
|
@ -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 <paths.h>
|
||||
|
||||
#define _PATH_SLOGGER "/sbin/session_logger"
|
||||
#define _PATH_RUNCOM "/etc/rc"
|
||||
|
|
@ -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 <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: fattr.c,v 1.10 2009/06/19 12:55:45 stacktic Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
#include <err.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
|
@ -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 *);
|
||||
|
|
@ -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 <bsd.own.mk>
|
||||
|
||||
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 <bsd.prog.mk>
|
||||
|
|
@ -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 <sys/ufs/ext2fs.h> */
|
||||
#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 */
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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.
|
||||
|
|
@ -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 <sys/cdefs.h>
|
||||
#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 <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/disk.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <ufs/ext2fs/ext2fs.h>
|
||||
#include <ufs/ext2fs/ext2fs_dinode.h>
|
||||
|
||||
#include <disktab.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <paths.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <util.h>
|
||||
#include <mntopts.h>
|
||||
|
||||
#if defined(__minix)
|
||||
#include <minix/partition.h>
|
||||
#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);
|
||||
}
|
||||
|
|
@ -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 <bsd.prog.mk>
|
||||
|
|
@ -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 .
|
||||
|
|
@ -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 <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: ping_hostops.c,v 1.2 2011/03/11 09:59:56 pooka Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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,
|
||||
};
|
||||
|
|
@ -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 <sys/types.h>
|
||||
|
||||
#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_ */
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
# $NetBSD: Makefile,v 1.16 2015/09/09 10:06:05 ozaki-r Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
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 <bsd.prog.mk>
|
||||
|
|
@ -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 .
|
||||
|
|
@ -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 <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: ping6_hostops.c,v 1.1 2015/08/06 14:45:54 ozaki-r Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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,
|
||||
};
|
||||
|
|
@ -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 <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: ping6_rumpops.c,v 1.1 2015/08/06 14:45:54 ozaki-r Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rump/rump.h>
|
||||
#include <rump/rump_syscalls.h>
|
||||
#include <rump/rumpclient.h>
|
||||
|
||||
#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,
|
||||
};
|
||||
|
|
@ -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 <sys/types.h>
|
||||
|
||||
#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_ */
|
||||
|
|
@ -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 <bsd.prog.mk>
|
||||
|
|
@ -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 <sys/cdefs.h>
|
||||
#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 <sys/types.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <err.h>
|
||||
#include <util.h>
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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 '}'
|
||||
}
|
||||
|
|
@ -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 .
|
||||
|
|
@ -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 <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <util.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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 <bsd.prog.mk>
|
||||
|
|
@ -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 <paths.h>
|
||||
|
||||
#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"
|
||||
|
|
@ -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 .
|
||||
|
|
@ -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 <sys/cdefs.h>
|
||||
#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 <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <tzfile.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
|
@ -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 <bsd.own.mk>
|
||||
#DBG=-g
|
||||
|
||||
RUMPPRG=sysctl
|
||||
MAN= sysctl.8
|
||||
|
||||
SRCS= sysctl.c
|
||||
|
||||
.PATH: ${.CURDIR}/../../lib/libc/gen
|
||||
CPPFLAGS+= -DRUMP_ACTION
|
||||
RUMPSRCS+= sysctlbyname.c sysctlgetmibinfo.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
@ -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 <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/unistd.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
|
@ -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 <sys/types.h>
|
||||
|
||||
#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_ */
|
||||
|
|
@ -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 .
|
||||
2800
sbin/sysctl/sysctl.c
2800
sbin/sysctl/sysctl.c
File diff suppressed because it is too large
Load Diff
|
|
@ -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 <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: sysctl_hostops.c,v 1.1 2010/12/13 17:47:40 pooka Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include "prog_ops.h"
|
||||
|
||||
const struct prog_ops prog_ops = {
|
||||
.op_sysctl = sysctl,
|
||||
};
|
||||
|
|
@ -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 <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: sysctl_rumpops.c,v 1.1 2010/12/13 17:47:40 pooka Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <rump/rump.h>
|
||||
#include <rump/rump_syscalls.h>
|
||||
#include <rump/rumpclient.h>
|
||||
|
||||
#include "prog_ops.h"
|
||||
|
||||
const struct prog_ops prog_ops = {
|
||||
.op_init = rumpclient_init,
|
||||
|
||||
.op_sysctl = rump_sys___sysctl,
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user