Merge pull request #12 from Oichkatzelesfrettschen/eirikr/delete-files-mentioning-netbsd-in-batches

This commit is contained in:
Eirikr Hinngart 2025-05-30 11:28:55 -07:00 committed by GitHub
commit 0af921fe36
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
50 changed files with 0 additions and 16430 deletions

View File

@ -1,12 +0,0 @@
# from: @(#)Makefile 8.1 (Berkeley) 6/6/93
# $NetBSD: Makefile,v 1.6 2011/01/13 23:44:11 haad Exp $
PROG= chown
CPPFLAGS+=-DSUPPORT_DOT
MAN= chgrp.1 chown.8
SYMLINKS+= ${BINDIR}/chown /bin/chgrp
SYMLINKS+= ${BINDIR}/chown /usr/bin/chgrp
SYMLINKS+= ${BINDIR}/chown /usr/sbin/chown
.include <bsd.prog.mk>

View File

@ -1,171 +0,0 @@
.\" Copyright (c) 1983, 1990, 1993, 1994, 2003
.\" The Regents of the University of California. All rights reserved.
.\"
.\" This code is derived from software contributed to Berkeley by
.\" the Institute of Electrical and Electronics Engineers, 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.
.\"
.\" from: @(#)chgrp.1 8.3 (Berkeley) 3/31/94
.\" $NetBSD: chgrp.1,v 1.6 2013/12/17 09:54:08 apb Exp $
.\"
.Dd October 22, 2012
.Dt CHGRP 1
.Os
.Sh NAME
.Nm chgrp
.Nd change group
.Sh SYNOPSIS
.Nm
.Oo
.Fl R
.Op Fl H | Fl L | Fl P
.Oc
.Op Fl fhv
.Ar group
.Ar
.Nm
.Oo
.Fl R
.Op Fl H | Fl L | Fl P
.Oc
.Op Fl fhv
.Fl Fl reference=rfile
.Ar
.Sh DESCRIPTION
The
.Nm
utility sets the group ID of the file named by each
.Ar file
operand to the
.Ar group
ID specified by the group operand,
or to the group of the given
.Ar rfile ,
specified by the
.Fl Fl reference
argument.
.Pp
Options:
.Bl -tag -width Ds
.It Fl H
If the
.Fl R
option is specified, symbolic links on the command line are followed.
(Symbolic links encountered in the tree traversal are not followed.)
.It Fl L
If the
.Fl R
option is specified, all symbolic links are followed.
.It Fl P
If the
.Fl R
option is specified, no symbolic links are followed.
.It Fl R
Change the group ID for the file hierarchies rooted
in the files instead of just the files themselves.
.It Fl f
The force option ignores errors, except for usage errors and doesn't
query about strange modes (unless the user does not have proper permissions).
.It Fl h
If
.Ar file
is a symbolic link, the group of the link is changed.
.It Fl v
Cause
.Nm
to be verbose, showing files as they are processed.
.El
.Pp
If
.Fl h
is not given, unless the
.Fl H
or
.Fl L
option is set,
.Nm
on a symbolic link always succeeds and has no effect.
The
.Fl H ,
.Fl L
and
.Fl P
options are ignored unless the
.Fl R
option is specified.
In addition, these options override each other and the
command's actions are determined by the last one specified.
The default is as if the
.Fl P
option had been specified.
.Pp
The
.Ar group
operand can be either a group name from the group database,
or a numeric group ID.
Since it is valid to have a group name that is numeric (and
doesn't have the numeric ID that matches its name) the name lookup
is always done first.
Preceding the ID with a ``#'' character will force it to be taken
as a number.
.Pp
The user invoking
.Nm
must belong to the specified group and be the owner of the file,
or be the super-user.
.Pp
Unless invoked by the super-user,
.Nm
clears the set-user-id and set-group-id bits on a file to prevent
accidental or mischievous creation of set-user-id or set-group-id
programs.
.Pp
The
.Nm
utility exits 0 on success, and \*[Gt]0 if an error occurs.
.Sh FILES
.Bl -tag -width /etc/group -compact
.It Pa /etc/group
Group ID file
.El
.Sh SEE ALSO
.Xr chown 2 ,
.Xr lchown 2 ,
.Xr fts 3 ,
.Xr group 5 ,
.Xr passwd 5 ,
.Xr symlink 7 ,
.Xr chown 8
.Sh STANDARDS
The
.Nm
utility is expected to be POSIX 1003.2 compatible.
.Pp
The
.Fl v
option and the use of ``#'' to force a numeric group ID
are extensions to
.St -p1003.2 .

View File

@ -1,186 +0,0 @@
.\" Copyright (c) 1990, 1991, 1993, 1994, 2003
.\" 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.
.\"
.\" from: @(#)chown.8 8.3 (Berkeley) 3/31/94
.\" $NetBSD: chown.8,v 1.10 2016/09/11 01:23:26 sevan Exp $
.\"
.Dd September 11, 2016
.Dt CHOWN 8
.Os
.Sh NAME
.Nm chown
.Nd change file owner and group
.Sh SYNOPSIS
.Nm
.Oo
.Fl R
.Op Fl H | Fl L | Fl P
.Oc
.Op Fl fhv
.Ar owner Ns Op Ar :group
.Ar
.Nm
.Oo
.Fl R
.Op Fl H | Fl L | Fl P
.Oc
.Op Fl fhv
.Ar :group
.Ar
.Nm
.Oo
.Fl R
.Op Fl H | Fl L | Fl P
.Oc
.Op Fl fhv
.Fl Fl reference=rfile
.Ar
.Sh DESCRIPTION
.Nm
sets the user ID and/or the group ID of the specified files.
Symbolic links named by arguments are silently left unchanged unless
.Fl h
is used.
.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl H
If the
.Fl R
option is specified, symbolic links on the command line are followed.
(Symbolic links encountered in the tree traversal are not followed.)
.It Fl L
If the
.Fl R
option is specified, all symbolic links are followed.
.It Fl P
If the
.Fl R
option is specified, no symbolic links are followed.
.It Fl R
Change the user ID and/or the group ID for the file hierarchies rooted
in the files instead of just the files themselves.
.It Fl f
Do not report any failure to change file owner or group, nor modify
the exit status to reflect such failures.
.It Fl h
If
.Ar file
is a symbolic link, the owner and/or group of the link is changed.
.It Fl v
Cause
.Nm
to be verbose, showing files as they are processed.
.El
.Pp
The
.Fl H ,
.Fl L
and
.Fl P
options are ignored unless the
.Fl R
option is specified.
In addition, these options override each other and the
command's actions are determined by the last one specified.
The default is as if the
.Fl P
option had been specified.
.Pp
The
.Fl L
option cannot be used together with the
.Fl h
option.
.Pp
The
.Ar owner
and
.Ar group
operands are both optional, however, one must be specified; alternatively,
both the owner and group may be specified using a reference
.Ar rfile
specified using the
.Fl Fl reference
argument.
If the
.Ar group
operand is specified, it must be preceded by a colon (``:'') character.
.Pp
The
.Ar owner
may be either a user name or a numeric user ID.
The
.Ar group
may be either a group name or a numeric group ID.
Since it is valid to have a user or group name that is numeric (and
does not have the numeric ID that matches its name) the name lookup
is always done first.
Preceding an ID with a ``#'' character will force it to be taken
as a number.
.Pp
The ownership of a file may only be altered by a super-user for
obvious security reasons.
.Pp
Unless invoked by the super-user,
.Nm
clears the set-user-id and set-group-id bits on a file to prevent
accidental or mischievous creation of set-user-id and set-group-id
programs.
.Pp
The
.Nm
utility exits 0 on success, and \*[Gt]0 if an error occurs.
.Sh COMPATIBILITY
Previous versions of the
.Nm
utility used the dot (``.'') character to distinguish the group name.
This has been changed to be a colon (``:'') character so that user and
group names may contain the dot character.
.Sh SEE ALSO
.Xr chflags 1 ,
.Xr chgrp 1 ,
.Xr find 1 ,
.Xr chown 2 ,
.Xr lchown 2 ,
.Xr fts 3 ,
.Xr symlink 7
.Sh HISTORY
A
.Nm
utility appeared in
.At v1 .
.Sh STANDARDS
The
.Nm
command is expected to be POSIX 1003.2 compliant.
.Pp
The
.Fl v
option and the use of ``#'' to force a numeric lookup
are extensions to
.St -p1003.2 .

View File

@ -1,302 +0,0 @@
/* $NetBSD: chown.c,v 1.8 2012/10/24 01:12:51 enami Exp $ */
/*
* Copyright (c) 1988, 1993, 1994, 2003
* 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, 1993, 1994, 2003\
The Regents of the University of California. All rights reserved.");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)chown.c 8.8 (Berkeley) 4/4/94";
#else
__RCSID("$NetBSD: chown.c,v 1.8 2012/10/24 01:12:51 enami Exp $");
#endif
#endif /* not lint */
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <dirent.h>
#include <err.h>
#include <errno.h>
#include <locale.h>
#include <fts.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
static void a_gid(const char *);
static void a_uid(const char *);
static id_t id(const char *, const char *);
__dead static void usage(void);
static uid_t uid;
static gid_t gid;
static int ischown;
static const char *myname;
struct option chown_longopts[] = {
{ "reference", required_argument, 0,
1 },
{ NULL, 0, 0,
0 },
};
int
main(int argc, char **argv)
{
FTS *ftsp;
FTSENT *p;
int Hflag, Lflag, Rflag, ch, fflag, fts_options, hflag, rval, vflag;
char *cp, *reference;
int (*change_owner)(const char *, uid_t, gid_t);
setprogname(*argv);
(void)setlocale(LC_ALL, "");
myname = getprogname();
ischown = (myname[2] == 'o');
reference = NULL;
Hflag = Lflag = Rflag = fflag = hflag = vflag = 0;
while ((ch = getopt_long(argc, argv, "HLPRfhv",
chown_longopts, NULL)) != -1)
switch (ch) {
case 1:
reference = optarg;
break;
case 'H':
Hflag = 1;
Lflag = 0;
break;
case 'L':
Lflag = 1;
Hflag = 0;
break;
case 'P':
Hflag = Lflag = 0;
break;
case 'R':
Rflag = 1;
break;
case 'f':
fflag = 1;
break;
case 'h':
/*
* In System V the -h option causes chown/chgrp to
* change the owner/group of the symbolic link.
* 4.4BSD's symbolic links didn't have owners/groups,
* so it was an undocumented noop.
* In NetBSD 1.3, lchown(2) is introduced.
*/
hflag = 1;
break;
case 'v':
vflag = 1;
break;
case '?':
default:
usage();
}
argv += optind;
argc -= optind;
if (argc == 0 || (argc == 1 && reference == NULL))
usage();
fts_options = FTS_PHYSICAL;
if (Rflag) {
if (Hflag)
fts_options |= FTS_COMFOLLOW;
if (Lflag) {
if (hflag)
errx(EXIT_FAILURE,
"the -L and -h options "
"may not be specified together.");
fts_options &= ~FTS_PHYSICAL;
fts_options |= FTS_LOGICAL;
}
} else if (!hflag)
fts_options |= FTS_COMFOLLOW;
uid = (uid_t)-1;
gid = (gid_t)-1;
if (reference == NULL) {
if (ischown) {
if ((cp = strchr(*argv, ':')) != NULL) {
*cp++ = '\0';
a_gid(cp);
}
#ifdef SUPPORT_DOT
else if ((cp = strrchr(*argv, '.')) != NULL) {
if (uid_from_user(*argv, &uid) == -1) {
*cp++ = '\0';
a_gid(cp);
}
}
#endif
a_uid(*argv);
} else
a_gid(*argv);
argv++;
} else {
struct stat st;
if (stat(reference, &st) == -1)
err(EXIT_FAILURE, "Cannot stat `%s'", reference);
if (ischown)
uid = st.st_uid;
gid = st.st_gid;
}
if ((ftsp = fts_open(argv, fts_options, NULL)) == NULL)
err(EXIT_FAILURE, "fts_open");
for (rval = EXIT_SUCCESS; (p = fts_read(ftsp)) != NULL;) {
change_owner = chown;
switch (p->fts_info) {
case FTS_D:
if (!Rflag) /* Change it at FTS_DP. */
fts_set(ftsp, p, FTS_SKIP);
continue;
case FTS_DNR: /* Warn, chown, continue. */
warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
rval = EXIT_FAILURE;
break;
case FTS_ERR: /* Warn, continue. */
case FTS_NS:
warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
rval = EXIT_FAILURE;
continue;
case FTS_SL: /* Ignore unless -h. */
/*
* All symlinks we found while doing a physical
* walk end up here.
*/
if (!hflag)
continue;
/*
* Note that if we follow a symlink, fts_info is
* not FTS_SL but FTS_F or whatever. And we should
* use lchown only for FTS_SL and should use chown
* for others.
*/
change_owner = lchown;
break;
case FTS_SLNONE: /* Ignore. */
/*
* The only symlinks that end up here are ones that
* don't point to anything. Note that if we are
* doing a phisycal walk, we never reach here unless
* we asked to follow explicitly.
*/
continue;
default:
break;
}
if ((*change_owner)(p->fts_accpath, uid, gid) && !fflag) {
warn("%s", p->fts_path);
rval = EXIT_FAILURE;
} else {
if (vflag)
printf("%s\n", p->fts_path);
}
}
if (errno)
err(EXIT_FAILURE, "fts_read");
exit(rval);
/* NOTREACHED */
}
static void
a_gid(const char *s)
{
struct group *gr;
if (*s == '\0') /* Argument was "uid[:.]". */
return;
gr = *s == '#' ? NULL : getgrnam(s);
if (gr == NULL)
gid = id(s, "group");
else
gid = gr->gr_gid;
return;
}
static void
a_uid(const char *s)
{
if (*s == '\0') /* Argument was "[:.]gid". */
return;
if (*s == '#' || uid_from_user(s, &uid) == -1) {
uid = id(s, "user");
}
return;
}
static id_t
id(const char *name, const char *type)
{
id_t val;
char *ep;
errno = 0;
if (*name == '#')
name++;
val = (id_t)strtoul(name, &ep, 10);
if (errno)
err(EXIT_FAILURE, "%s", name);
if (*ep != '\0')
errx(EXIT_FAILURE, "%s: invalid %s name", name, type);
return (val);
}
static void
usage(void)
{
(void)fprintf(stderr,
"Usage: %s [-R [-H | -L | -P]] [-fhv] %s file ...\n"
"\t%s [-R [-H | -L | -P]] [-fhv] --reference=rfile file ...\n",
myname, ischown ? "owner:group|owner|:group" : "group",
myname);
exit(EXIT_FAILURE);
}

View File

@ -1,43 +0,0 @@
# $NetBSD: Makefile,v 1.56 2015/05/19 08:14:38 ozaki-r Exp $
# @(#)Makefile 8.1 (Berkeley) 6/5/93
# when making a change to this file, please check if the change is
# also needed for src/distrib/utils/x_ifconfig.
# such stuff should be into Makefile.inc.
.include <bsd.own.mk>
RUMPPRG=ifconfig
MAN= ifconfig.8
.if defined(__MINIX)
CWARNFLAGS.gcc+= -Wno-unused-but-set-variable
.endif # defined(__MINIX)
#DBG+=-g
SRCS= af_atalk.c af_link.c carp.c
.if (${USE_INET6} != "no")
CPPFLAGS+= -DINET6
SRCS+= af_inet6.c
.endif
.include "Makefile.inc"
.PATH: ${.CURDIR}/../../lib/libc/net
RUMPSRCS= getifaddrs.c getnameinfo.c if_indextoname.c
.if (${MKRUMP} != "no")
CPPFLAGS+= -DRUMP_ACTION
.endif
.ifdef SMALLPROG
CPPFLAGS+=-DSMALL
.endif
CPPFLAGS+=-I${NETBSDSRCDIR}/sys/dist/pf/
SRCS+= pfsync.c
.if ${MACHINE_ARCH} == "m68000"
# XXX workaround for gcc -O1 bug (PR bin/40036 and toolchain/40066)
COPTS.ifconfig.c+= -fno-loop-optimize
.endif
.include <bsd.prog.mk>

View File

@ -1,179 +0,0 @@
/* $NetBSD: af_inetany.c,v 1.17 2012/12/30 22:52:35 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: af_inetany.c,v 1.17 2012/12/30 22:52:35 christos 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 <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 *
loadbuf(const struct apbuf *b, const struct paddr_prefix *pfx)
{
return memcpy(b->buf, &pfx->pfx_addr,
MIN(b->buflen, pfx->pfx_addr.sa_len));
}
void
commit_address(prop_dictionary_t env, prop_dictionary_t oenv,
const struct afparam *param)
{
const char *ifname;
int af, rc, s;
bool alias, delete, replace;
prop_data_t d;
const struct paddr_prefix *addr, *brd, *dst, *mask;
unsigned short flags;
if ((af = getaf(env)) == -1)
af = AF_INET;
if ((s = getsock(af)) == -1)
err(EXIT_FAILURE, "%s: getsock", __func__);
if ((ifname = getifname(env)) == NULL)
err(EXIT_FAILURE, "%s: getifname", __func__);
strlcpy(param->name[0].buf, ifname, param->name[0].buflen);
strlcpy(param->name[1].buf, ifname, param->name[1].buflen);
if ((d = (prop_data_t)prop_dictionary_get(env, "address")) != NULL)
addr = prop_data_data_nocopy(d);
else if (!prop_dictionary_get_bool(env, "alias", &alias) || alias ||
param->gifaddr.cmd == 0)
return;
else if (prog_ioctl(s, param->gifaddr.cmd, param->dgreq.buf) == -1)
err(EXIT_FAILURE, "%s", param->gifaddr.desc);
else if (prog_ioctl(s, param->difaddr.cmd, param->dgreq.buf) == -1)
err(EXIT_FAILURE, "%s", param->difaddr.desc);
else
return;
if ((d = (prop_data_t)prop_dictionary_get(env, "dst")) != NULL)
dst = prop_data_data_nocopy(d);
else
dst = NULL;
if ((d = (prop_data_t)prop_dictionary_get(env, "netmask")) != NULL)
mask = prop_data_data_nocopy(d);
else
mask = NULL;
if ((d = (prop_data_t)prop_dictionary_get(env, "broadcast")) != NULL)
brd = prop_data_data_nocopy(d);
else
brd = NULL;
if (!prop_dictionary_get_bool(env, "alias", &alias)) {
delete = false;
replace = (param->gifaddr.cmd != 0);
} else {
replace = false;
delete = !alias;
}
loadbuf(&param->addr, addr);
/* TBD: read matching ifaddr from kernel, use the netmask as default
* TBD: handle preference
*/
if (getifflags(env, oenv, &flags) == -1)
err(EXIT_FAILURE, "%s: getifflags", __func__);
switch (flags & (IFF_BROADCAST|IFF_POINTOPOINT)) {
case IFF_BROADCAST:
if (brd != NULL)
loadbuf(&param->brd, brd);
/*FALLTHROUGH*/
case 0:
break;
case IFF_POINTOPOINT:
if (brd != NULL) {
errx(EXIT_FAILURE, "%s is not a broadcast interface",
ifname);
}
if (dst != NULL)
loadbuf(&param->dst, dst);
break;
case IFF_BROADCAST|IFF_POINTOPOINT:
errx(EXIT_FAILURE, "unsupported interface flags");
}
if (param->mask.buf == NULL) {
if (mask != NULL)
errx(EXIT_FAILURE, "netmask not supported");
} else if (mask != NULL)
loadbuf(&param->mask, mask);
else if (param->defmask.buf != NULL) {
memcpy(param->mask.buf, param->defmask.buf,
MIN(param->mask.buflen, param->defmask.buflen));
}
if (replace) {
if (prog_ioctl(s, param->gifaddr.cmd, param->dgreq.buf) == 0) {
rc = prog_ioctl(s, param->difaddr.cmd, param->dgreq.buf);
if (rc == -1)
err(EXIT_FAILURE, "%s", param->difaddr.desc);
} else if (errno == EADDRNOTAVAIL)
; /* No address was assigned yet. */
else
err(EXIT_FAILURE, "%s", param->gifaddr.desc);
} else if (delete) {
loadbuf(&param->dgaddr, addr);
if (prog_ioctl(s, param->difaddr.cmd, param->dgreq.buf) == -1)
err(EXIT_FAILURE, "%s", param->difaddr.desc);
return;
}
if (param->pre_aifaddr != NULL &&
(*param->pre_aifaddr)(env, param) == -1)
err(EXIT_FAILURE, "pre-%s", param->aifaddr.desc);
if (prog_ioctl(s, param->aifaddr.cmd, param->req.buf) == -1)
err(EXIT_FAILURE, "%s", param->aifaddr.desc);
}

View File

@ -1,195 +0,0 @@
/* $NetBSD: agr.c,v 1.15 2008/07/15 21:27:58 dyoung Exp $ */
/*-
* Copyright (c)2005 YAMAMOTO Takashi,
* 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>
#if !defined(lint)
__RCSID("$NetBSD: agr.c,v 1.15 2008/07/15 21:27:58 dyoung Exp $");
#endif /* !defined(lint) */
#include <sys/param.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/agr/if_agrioctl.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <util.h>
#include "env.h"
#include "extern.h"
#include "parse.h"
#include "util.h"
static int agrsetport(prop_dictionary_t, prop_dictionary_t);
static void agr_constructor(void) __attribute__((constructor));
static int checkifname(prop_dictionary_t);
static void assertifname(prop_dictionary_t);
static struct piface agrif = PIFACE_INITIALIZER(&agrif, "agr interface",
agrsetport, "agrport", &command_root.pb_parser);
static const struct kwinst agrkw[] = {
{.k_word = "agrport", .k_type = KW_T_INT, .k_int = AGRCMD_ADDPORT,
.k_nextparser = &agrif.pif_parser}
, {.k_word = "-agrport", .k_type = KW_T_INT, .k_int = AGRCMD_REMPORT,
.k_nextparser = &agrif.pif_parser}
};
struct pkw agr = PKW_INITIALIZER(&agr, "agr", NULL, "agrcmd",
agrkw, __arraycount(agrkw), NULL);
static int
checkifname(prop_dictionary_t env)
{
const char *ifname;
if ((ifname = getifname(env)) == NULL)
return 1;
return strncmp(ifname, "agr", 3) != 0 ||
!isdigit((unsigned char)ifname[3]);
}
static void
assertifname(prop_dictionary_t env)
{
if (checkifname(env))
errx(EXIT_FAILURE, "valid only with agr(4) interfaces");
}
int
agrsetport(prop_dictionary_t env, prop_dictionary_t oenv)
{
char buf[IFNAMSIZ];
struct agrreq ar;
const char *port;
int64_t cmd;
if (!prop_dictionary_get_int64(env, "agrcmd", &cmd)) {
warnx("%s.%d", __func__, __LINE__);
errno = ENOENT;
return -1;
}
if (!prop_dictionary_get_cstring_nocopy(env, "agrport", &port)) {
warnx("%s.%d", __func__, __LINE__);
errno = ENOENT;
return -1;
}
strlcpy(buf, port, sizeof(buf));
assertifname(env);
memset(&ar, 0, sizeof(ar));
ar.ar_version = AGRREQ_VERSION;
ar.ar_cmd = cmd;
ar.ar_buf = buf;
ar.ar_buflen = strlen(buf);
if (indirect_ioctl(env, SIOCSETAGR, &ar) == -1)
err(EXIT_FAILURE, "SIOCSETAGR");
return 0;
}
static void
agr_status(prop_dictionary_t env, prop_dictionary_t oenv)
{
struct agrreq ar;
void *buf = NULL;
size_t buflen = 0;
struct agrportlist *apl;
struct agrportinfo *api;
int i;
if (checkifname(env))
return;
again:
memset(&ar, 0, sizeof(ar));
ar.ar_version = AGRREQ_VERSION;
ar.ar_cmd = AGRCMD_PORTLIST;
ar.ar_buf = buf;
ar.ar_buflen = buflen;
if (indirect_ioctl(env, SIOCGETAGR, &ar) == -1) {
if (errno != E2BIG) {
warn("SIOCGETAGR");
return;
}
free(buf);
buf = NULL;
buflen = 0;
goto again;
}
if (buf == NULL) {
buflen = ar.ar_buflen;
buf = malloc(buflen);
if (buf == NULL) {
err(EXIT_FAILURE, "agr_status");
}
goto again;
}
apl = buf;
api = (void *)(apl + 1);
for (i = 0; i < apl->apl_nports; i++) {
char tmp[256];
snprintb(tmp, sizeof(tmp), AGRPORTINFO_BITS, api->api_flags);
printf("\tagrport: %s, flags=%s\n", api->api_ifname, tmp);
api++;
}
}
static status_func_t status;
static usage_func_t usage;
static cmdloop_branch_t branch;
static void
agr_usage(prop_dictionary_t env)
{
fprintf(stderr, "\t[ agrport i ] [ -agrport i ]\n");
}
static void
agr_constructor(void)
{
status_func_init(&status, agr_status);
usage_func_init(&usage, agr_usage);
register_status(&status);
register_usage(&usage);
cmdloop_branch_init(&branch, &agr.pk_parser);
register_cmdloop_branch(&branch);
}

View File

@ -1,295 +0,0 @@
/* $NetBSD: carp.c,v 1.13 2009/09/11 23:22:28 dyoung Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff. All rights reserved.
* Copyright (c) 2003 Ryan McBride. 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 OR HIS RELATIVES 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 MIND, 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: carp.c,v 1.13 2009/09/11 23:22:28 dyoung 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 <netinet/ip_carp.h>
#include <net/route.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 carp_constructor(void) __attribute__((constructor));
static void carp_status(prop_dictionary_t, prop_dictionary_t);
static int setcarp_advbase(prop_dictionary_t, prop_dictionary_t);
static int setcarp_advskew(prop_dictionary_t, prop_dictionary_t);
static int setcarp_passwd(prop_dictionary_t, prop_dictionary_t);
static int setcarp_vhid(prop_dictionary_t, prop_dictionary_t);
static int setcarp_state(prop_dictionary_t, prop_dictionary_t);
static int setcarpdev(prop_dictionary_t, prop_dictionary_t);
static const char *carp_states[] = { CARP_STATES };
struct kwinst carpstatekw[] = {
{.k_word = "INIT", .k_nextparser = &command_root.pb_parser}
, {.k_word = "BACKUP", .k_nextparser = &command_root.pb_parser}
, {.k_word = "MASTER", .k_nextparser = &command_root.pb_parser}
};
struct pinteger parse_advbase = PINTEGER_INITIALIZER1(&parse_advbase, "advbase",
0, 255, 10, setcarp_advbase, "advbase", &command_root.pb_parser);
struct pinteger parse_advskew = PINTEGER_INITIALIZER1(&parse_advskew, "advskew",
0, 254, 10, setcarp_advskew, "advskew", &command_root.pb_parser);
struct piface carpdev = PIFACE_INITIALIZER(&carpdev, "carpdev", setcarpdev,
"carpdev", &command_root.pb_parser);
struct pkw carpstate = PKW_INITIALIZER(&carpstate, "carp state", setcarp_state,
"carp_state", carpstatekw, __arraycount(carpstatekw),
&command_root.pb_parser);
struct pstr pass = PSTR_INITIALIZER(&pass, "pass", setcarp_passwd,
"pass", &command_root.pb_parser);
struct pinteger parse_vhid = PINTEGER_INITIALIZER1(&vhid, "vhid",
0, 255, 10, setcarp_vhid, "vhid", &command_root.pb_parser);
static const struct kwinst carpkw[] = {
{.k_word = "advbase", .k_nextparser = &parse_advbase.pi_parser}
, {.k_word = "advskew", .k_nextparser = &parse_advskew.pi_parser}
, {.k_word = "carpdev", .k_nextparser = &carpdev.pif_parser}
, {.k_word = "-carpdev", .k_key = "carpdev", .k_type = KW_T_STR,
.k_str = "", .k_exec = setcarpdev,
.k_nextparser = &command_root.pb_parser}
, {.k_word = "pass", .k_nextparser = &pass.ps_parser}
, {.k_word = "state", .k_nextparser = &carpstate.pk_parser}
, {.k_word = "vhid", .k_nextparser = &parse_vhid.pi_parser}
};
struct pkw carp = PKW_INITIALIZER(&carp, "CARP", NULL, NULL,
carpkw, __arraycount(carpkw), NULL);
static void
carp_set(prop_dictionary_t env, struct carpreq *carpr)
{
if (indirect_ioctl(env, SIOCSVH, carpr) == -1)
err(EXIT_FAILURE, "SIOCSVH");
}
static int
carp_get1(prop_dictionary_t env, struct carpreq *carpr)
{
memset(carpr, 0, sizeof(*carpr));
return indirect_ioctl(env, SIOCGVH, carpr);
}
static void
carp_get(prop_dictionary_t env, struct carpreq *carpr)
{
if (carp_get1(env, carpr) == -1)
err(EXIT_FAILURE, "SIOCGVH");
}
static void
carp_status(prop_dictionary_t env, prop_dictionary_t oenv)
{
const char *state;
struct carpreq carpr;
if (carp_get1(env, &carpr) == -1)
return;
if (carpr.carpr_vhid <= 0)
return;
if (carpr.carpr_state > CARP_MAXSTATE)
state = "<UNKNOWN>";
else
state = carp_states[carpr.carpr_state];
printf("\tcarp: %s carpdev %s vhid %d advbase %d advskew %d\n",
state, carpr.carpr_carpdev[0] != '\0' ?
carpr.carpr_carpdev : "none", carpr.carpr_vhid,
carpr.carpr_advbase, carpr.carpr_advskew);
}
int
setcarp_passwd(prop_dictionary_t env, prop_dictionary_t oenv)
{
struct carpreq carpr;
prop_data_t data;
data = (prop_data_t)prop_dictionary_get(env, "pass");
if (data == NULL) {
errno = ENOENT;
return -1;
}
carp_get(env, &carpr);
memset(carpr.carpr_key, 0, sizeof(carpr.carpr_key));
/* XXX Should hash the password into the key here, perhaps? */
strlcpy((char *)carpr.carpr_key, prop_data_data_nocopy(data),
MIN(CARP_KEY_LEN, prop_data_size(data)));
carp_set(env, &carpr);
return 0;
}
int
setcarp_vhid(prop_dictionary_t env, prop_dictionary_t oenv)
{
struct carpreq carpr;
int64_t vhid;
if (!prop_dictionary_get_int64(env, "vhid", &vhid)) {
errno = ENOENT;
return -1;
}
carp_get(env, &carpr);
carpr.carpr_vhid = vhid;
carp_set(env, &carpr);
return 0;
}
int
setcarp_advskew(prop_dictionary_t env, prop_dictionary_t oenv)
{
struct carpreq carpr;
int64_t advskew;
if (!prop_dictionary_get_int64(env, "advskew", &advskew)) {
errno = ENOENT;
return -1;
}
carp_get(env, &carpr);
carpr.carpr_advskew = advskew;
carp_set(env, &carpr);
return 0;
}
/* ARGSUSED */
int
setcarp_advbase(prop_dictionary_t env, prop_dictionary_t oenv)
{
struct carpreq carpr;
int64_t advbase;
if (!prop_dictionary_get_int64(env, "advbase", &advbase)) {
errno = ENOENT;
return -1;
}
carp_get(env, &carpr);
carpr.carpr_advbase = advbase;
carp_set(env, &carpr);
return 0;
}
/* ARGSUSED */
static int
setcarp_state(prop_dictionary_t env, prop_dictionary_t oenv)
{
struct carpreq carpr;
int64_t carp_state;
if (!prop_dictionary_get_int64(env, "carp_state", &carp_state)) {
errno = ENOENT;
return -1;
}
carp_get(env, &carpr);
carpr.carpr_state = carp_state;
carp_set(env, &carpr);
return 0;
}
/* ARGSUSED */
int
setcarpdev(prop_dictionary_t env, prop_dictionary_t oenv)
{
struct carpreq carpr;
prop_string_t s;
s = (prop_string_t)prop_dictionary_get(env, "carpdev");
if (s == NULL) {
errno = ENOENT;
return -1;
}
carp_get(env, &carpr);
strlcpy(carpr.carpr_carpdev, prop_string_cstring_nocopy(s),
sizeof(carpr.carpr_carpdev));
carp_set(env, &carpr);
return 0;
}
static void
carp_usage(prop_dictionary_t env)
{
fprintf(stderr,
"\t[ advbase n ] [ advskew n ] [ carpdev iface ] "
"[ pass passphrase ] [ state state ] [ vhid n ]\n");
}
static void
carp_constructor(void)
{
cmdloop_branch_init(&branch, &carp.pk_parser);
register_cmdloop_branch(&branch);
status_func_init(&status, carp_status);
usage_func_init(&usage, carp_usage);
register_status(&status);
register_usage(&usage);
}

View File

@ -1,93 +0,0 @@
/* $NetBSD: extern.h,v 1.14 2009/08/07 18:53:37 dyoung 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.
*/
#ifndef _IFCONFIG_EXTERN_H
#define _IFCONFIG_EXTERN_H
#include <prop/proplib.h>
#include "util.h"
#define RIDADDR 0
#define ADDR 1
#define MASK 2
#define DSTADDR 3
typedef void (*usage_cb_t)(prop_dictionary_t);
typedef void (*status_cb_t)(prop_dictionary_t, prop_dictionary_t);
typedef void (*statistics_cb_t)(prop_dictionary_t);
enum flag_type {
FLAG_T_MOD = 0
, FLAG_T_CMD = 1
};
typedef enum flag_type flag_type_t;
struct statistics_func {
SIMPLEQ_ENTRY(statistics_func) f_next;
statistics_cb_t f_func;
};
struct usage_func {
SIMPLEQ_ENTRY(usage_func) f_next;
usage_cb_t f_func;
};
struct status_func {
SIMPLEQ_ENTRY(status_func) f_next;
status_cb_t f_func;
};
struct cmdloop_branch {
SIMPLEQ_ENTRY(cmdloop_branch) b_next;
struct parser *b_parser;
};
typedef struct statistics_func statistics_func_t;
typedef struct status_func status_func_t;
typedef struct usage_func usage_func_t;
typedef struct cmdloop_branch cmdloop_branch_t;
void cmdloop_branch_init(cmdloop_branch_t *, struct parser *);
int register_family(struct afswtch *);
int register_cmdloop_branch(cmdloop_branch_t *);
void statistics_func_init(statistics_func_t *, statistics_cb_t);
void status_func_init(status_func_t *, status_cb_t);
void usage_func_init(usage_func_t *, usage_cb_t);
int register_statistics(statistics_func_t *);
int register_status(status_func_t *);
int register_usage(usage_func_t *);
int register_flag(int);
bool get_flag(int);
extern bool lflag, Nflag, vflag, zflag;
#endif /* _IFCONFIG_EXTERN_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,920 +0,0 @@
.\" $NetBSD: ifconfig.8,v 1.109 2014/10/20 14:50:09 roy Exp $
.\"
.\" Copyright (c) 1983, 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.
.\"
.\" @(#)ifconfig.8 8.4 (Berkeley) 6/1/94
.\"
.Dd October 12, 2014
.Dt IFCONFIG 8
.Os
.Sh NAME
.Nm ifconfig
.Nd configure network interface parameters
.Sh SYNOPSIS
.Nm
.Op Fl N
.Ar interface address_family
.Oo
.Ar address
.Op Ar dest_address
.Oc
.Op Ar parameters
.Nm
.Op Fl hLmNvz
.Ar interface
.Op Ar protocol_family
.Nm
.Fl a
.Op Fl bdhLNmsuvz
.Op Ar protocol_family
.Nm
.Fl l
.Op Fl bdsu
.Nm
.Fl s
.Ar interface
.Nm
.Fl w
.Ar secs
.Nm
.Fl C
.Sh DESCRIPTION
.Nm
is used to assign an address
to a network interface and/or configure
network interface parameters.
.Nm
must be used at boot time to define the network address
of each interface present on a machine; it may also be used at
a later time to redefine an interface's address
or other operating parameters.
.Pp
Available operands for
.Nm :
.Bl -tag -width Ds
.It Ar address
For the
.Tn DARPA-Internet
family,
the address is either a host name present in the host name data
base,
.Xr hosts 5 ,
or a
.Tn DARPA
Internet address expressed in the Internet standard
.Dq dot notation .
For the Xerox Network Systems(tm) family,
addresses are
.Ar net:a.b.c.d.e.f ,
where
.Ar net
is the assigned network number
.Pq in decimal ,
and each of the six bytes of the host number,
.Ar a
through
.Ar f ,
are specified in hexadecimal.
The host number may be omitted on Ethernet interfaces,
which use the hardware physical address,
and on interfaces other than the first.
For the
.Tn ISO
family, addresses are specified as a long hexadecimal string,
as in the Xerox family.
However, two consecutive dots imply a zero
byte, and the dots are optional, if the user wishes to
.Pq carefully
count out long strings of digits in network byte order.
.It Ar address_family
Specifies the
.Ar address_family
which affects interpretation of the remaining parameters.
Since an interface can receive transmissions in differing protocols
with different naming schemes, specifying the address family is recommended.
The address or protocol families currently
supported are
.Dq inet ,
.Dq inet6 ,
.Dq atalk ,
.Dq iso ,
and
.Dq link .
.It Ar interface
The
.Ar interface
parameter is a string of the form
.Dq name unit ,
for example,
.Dq en0
.El
.Pp
The following parameters may be set with
.Nm :
.Bl -tag -width dest_addressxx
.It Cm active
This keyword applies when
.Nm
adds or modifies any link-layer address.
It indicates that
.Nm
should
.Dq activate
the address.
Activation makes an address the default source for transmissions
on the interface.
You may not delete the active address from an interface.
You must activate some other address, first.
.It Cm advbase Ar n
If the driver is a
.Xr carp 4
pseudo-device, set the base advertisement interval to
.Ar n
seconds.
This ia an 8-bit number; the default value is 1 second.
.It Cm advskew Ar n
If the driver is a
.Xr carp 4
pseudo-device, skew the advertisement interval by
.Ar n .
This is an 8-bit number; the default value is 0.
.Pp
Taken together the
.Cm advbase
indicate how frequently, in seconds, the host will advertise the fact that it
considers itself the master of the virtual host.
The formula is
.Cm advbase
+
.Pf ( Cm advskew
/ 256).
If the master does not advertise within three times this interval, this host
will begin advertising as master.
.It Cm alias
Establish an additional network address for this interface.
This is sometimes useful when changing network numbers, and
one wishes to accept packets addressed to the old interface.
.It Fl alias
Remove the specified network address alias.
.It Cm arp
Enable the use of the Address Resolution Protocol in mapping
between network level addresses and link level addresses
.Pq default .
This is currently implemented for mapping between
.Tn DARPA
Internet
addresses and Ethernet addresses.
.It Fl arp
Disable the use of the Address Resolution Protocol.
.It Cm anycast
.Pq inet6 only
Set the IPv6 anycast address bit.
.It Fl anycast
.Pq inet6 only
Clear the IPv6 anycast address bit.
.It Cm broadcast Ar mask
.Pq Inet only
Specify the address to use to represent broadcasts to the
network.
The default broadcast address is the address with a host part of all 1's.
.It Cm carpdev Ar iface
If the driver is a
.Xr carp 4
pseudo-device, attach it to
.Ar iface .
If not specified, the kernel will attempt to select an interface with
a subnet matching that of the carp interface.
.It Cm debug
Enable driver dependent debugging code; usually, this turns on
extra console error logging.
.It Fl debug
Disable driver dependent debugging code.
.It Cm delete
Remove the network address specified.
This would be used if you incorrectly specified an alias, or it
was no longer needed.
If you have incorrectly set an NS address having the side effect
of specifying the host portion, removing all NS addresses will
allow you to respecify the host portion.
.Cm delete
does not work for IPv6 addresses.
Use
.Fl alias
with explicit IPv6 address instead.
.It Ar dest_address
Specify the address of the correspondent on the other end
of a point to point link.
.It Cm down
Mark an interface ``down''.
When an interface is
marked ``down'', the system will not attempt to
transmit messages through that interface.
If possible, the interface will be reset to disable reception as well.
This action does not automatically disable routes using the interface.
.It Cm ipdst
This is used to specify an Internet host who is willing to receive
ip packets encapsulating NS packets bound for a remote network.
An apparent point to point link is constructed, and
the address specified will be taken as the NS address and network
of the destination.
IP encapsulation of
.Tn CLNP
packets is done differently.
.It Cm media Ar type
Set the media type of the interface to
.Ar type .
Some interfaces support the mutually exclusive use of one of several
different physical media connectors.
For example, a 10Mb/s Ethernet
interface might support the use of either
.Tn AUI
or twisted pair connectors.
Setting the media type to
.Dq 10base5
or
.Dq AUI
would change the currently active connector to the AUI port.
Setting it to
.Dq 10baseT
or
.Dq UTP
would activate twisted pair.
Refer to the interfaces' driver
specific man page for a complete list of the available types
and the
.Xr ifmedia 4
manual page for a list of media types.
See the
.Fl m
flag below.
.It Cm mediaopt Ar opts
Set the specified media options on the interface.
.Ar opts
is a comma delimited list of options to apply to the interface.
Refer to the interfaces' driver specific man page for a complete
list of available options.
Also see the
.Xr ifmedia 4
manual page for a list of media options.
.It Fl mediaopt Ar opts
Disable the specified media options on the interface.
.It Cm mode Ar mode
If the driver supports the media selection system, set the specified
operating mode on the interface to
.Ar mode .
For IEEE 802.11 wireless interfaces that support multiple operating modes
this directive is used to select between 802.11a
.Pq Dq 11a ,
802.11b
.Pq Dq 11b ,
and 802.11g
.Pq Dq 11g
operating modes.
.It Cm instance Ar minst
Set the media instance to
.Ar minst .
This is useful for devices which have multiple physical layer interfaces
.Pq PHYs .
Setting the instance on such devices may not be strictly required
by the network interface driver as the driver may take care of this
automatically; see the driver's manual page for more information.
.It Cm metric Ar n
Set the routing metric of the interface to
.Ar n ,
default 0.
The routing metric is used by the routing protocol
.Pq Xr routed 8 .
Higher metrics have the effect of making a route
less favorable; metrics are counted as addition hops
to the destination network or host.
.It Cm mtu Ar n
Set the maximum transmission unit of the interface to
.Ar n .
Most interfaces don't support this option.
.It Cm netmask Ar mask
.Pq inet, inet6, and ISO
Specify how much of the address to reserve for subdividing
networks into sub-networks.
The mask includes the network part of the local address
and the subnet part, which is taken from the host field of the address.
The mask can be specified as a single hexadecimal number
with a leading 0x, with a dot-notation Internet address,
or with a pseudo-network name listed in the network table
.Xr networks 5 .
The mask contains 1's for the bit positions in the 32-bit address
which are to be used for the network and subnet parts,
and 0's for the host part.
The mask should contain at least the standard network portion,
and the subnet field should be contiguous with the network
portion.
.Pp
For INET and INET6 addresses, the netmask can also be given with
slash-notation after the address
.Pq e.g 192.168.17.3/24 .
.\" see
.\" Xr eon 5 .
.It Cm nsellength Ar n
.Pf ( Tn ISO
only)
This specifies a trailing number of bytes for a received
.Tn NSAP
used for local identification, the remaining leading part of which is
taken to be the
.Tn NET
.Pq Network Entity Title .
The default value is 1, which is conformant to US
.Tn GOSIP .
When an ISO address is set in an ifconfig command,
it is really the
.Tn NSAP
which is being specified.
For example, in
.Tn US GOSIP ,
20 hex digits should be
specified in the
.Tn ISO NSAP
to be assigned to the interface.
There is some evidence that a number different from 1 may be useful
for
.Tn AFI
37 type addresses.
.It Cm state Ar state
Explicitly force the
.Xr carp 4
pseudo-device to enter this state.
Valid states are
.Ar init ,
.Ar backup ,
and
.Ar master .
.It Cm frag Ar threshold
.Pq IEEE 802.11 devices only
Configure the fragmentation threshold for IEEE 802.11-based wireless
network interfaces.
.It Cm rts Ar threshold
.Pq IEEE 802.11 devices only
Configure the RTS/CTS threshold for IEEE 802.11-based wireless
network interfaces.
This controls the number of bytes used for the RTS/CTS handshake boundary.
The
.Ar threshold
can be any value between 0 and 2347.
The default is 2347, which indicates the RTS/CTS mechanism should not be used.
.It Cm ssid Ar id
.Pq IEEE 802.11 devices only
Configure the Service Set Identifier (a.k.a. the network name)
for IEEE 802.11-based wireless network interfaces.
The
.Ar id
can either be any text string up to 32 characters in length,
or a series of up to 64 hexadecimal digits preceded by
.Dq 0x .
Setting
.Ar id
to the empty string allows the interface to connect to any available
access point.
.It Cm nwid Ar id
Synonym for
.Dq ssid .
.It Cm hidessid
.Pq IEEE 802.11 devices only
When operating as an access point, do not broadcast the SSID
in beacon frames or respond to probe request frames unless
they are directed to the ap (i.e., they include the ap's SSID).
By default, the SSID is included in beacon frames and
undirected probe request frames are answered.
.It Fl hidessid
.Pq IEEE 802.11 devices only
When operating as an access point, broadcast the SSID
in beacon frames and answer and respond to undirected probe
request frames (default).
.It Cm nwkey Ar key
.Pq IEEE 802.11 devices only
Enable WEP encryption for IEEE 802.11-based wireless network interfaces
with the
.Ar key .
The
.Ar key
can either be a string, a series of hexadecimal digits preceded by
.Dq 0x ,
or a set of keys in the form
.Ar n:k1,k2,k3,k4 ,
where
.Ar n
specifies which of keys will be used for all transmitted packets,
and four keys,
.Ar k1
through
.Ar k4 ,
are configured as WEP keys.
Note that the order must be match within same network if multiple keys
are used.
For IEEE 802.11 wireless network, the length of each key is restricted to
40 bits, i.e. 5-character string or 10 hexadecimal digits,
while the WaveLAN/IEEE Gold cards accept the 104 bits
.Pq 13 characters
key.
.It Cm nwkey Cm persist
.Pq IEEE 802.11 devices only
Enable WEP encryption for IEEE 802.11-based wireless network interfaces
with the persistent key written in the network card.
.It Cm nwkey Cm persist: Ns Ar key
.Pq IEEE 802.11 devices only
Write the
.Ar key
to the persistent memory of the network card, and
enable WEP encryption for IEEE 802.11-based wireless network interfaces
with the
.Ar key .
.It Fl nwkey
.Pq IEEE 802.11 devices only
Disable WEP encryption for IEEE 802.11-based wireless network interfaces.
.It Cm apbridge
.Pq IEEE 802.11 devices only
When operating as an access point, pass packets between
wireless clients directly (default).
.It Fl apbridge
.Pq IEEE 802.11 devices only
When operating as an access point, pass packets through
the system so that they can be forwared using some other mechanism.
Disabling the internal bridging is useful when traffic
is to be processed with packet filtering.
.It Cm pass Ar passphrase
If the driver is a
.Xr carp 4
pseudo-device, set the authentication key to
.Ar passphrase .
There is no passphrase by default
.It Cm powersave
.Pq IEEE 802.11 devices only
Enable 802.11 power saving mode.
.It Fl powersave
.Pq IEEE 802.11 devices only
Disable 802.11 power saving mode.
.It Cm powersavesleep Ar duration
.Pq IEEE 802.11 devices only
Set the receiver sleep duration in milliseconds for 802.11 power saving mode.
.It Cm bssid Ar bssid
.Pq IEEE 802.11 devices only
Set the desired BSSID for IEEE 802.11-based wireless network interfaces.
.It Fl bssid
.Pq IEEE 802.11 devices only
Unset the desired BSSID for IEEE 802.11-based wireless network interfaces.
The interface will automatically select a BSSID in this mode, which is
the default.
.It Cm chan Ar chan
.Pq IEEE 802.11 devices only
Select the channel
.Pq radio frequency
to be used for IEEE 802.11-based wireless network interfaces.
.It Fl chan
.Pq IEEE 802.11 devices only
Unset the desired channel to be used
for IEEE 802.11-based wireless network interfaces.
It doesn't affect the channel to be created for IBSS or hostap mode.
.It Cm list scan
.Pq IEEE 802.11 devices only
Display the access points and/or ad-hoc neighbors
located in the vicinity.
The
.Fl v
flag may be used to display long SSIDs.
.Fl v
also causes received information elements to be displayed symbolically.
The interface must be up before any scanning operation.
Only the super-user can use this command.
.It Cm tunnel Ar src_addr Ns Oo Ar ,src_port Oc Ar dest_addr Ns Oo Ar ,dest_port
.Oc
.Pq IP tunnel devices only
Configure the physical source and destination address for IP tunnel
interfaces, including
.Xr gif 4 .
The arguments
.Ar src_addr
and
.Ar dest_addr
are interpreted as the outer source/destination for the encapsulating
IPv4/IPv6 header.
.Pp
On a
.Xr gre 4
interface in UDP mode, the arguments
.Ar src_port
and
.Ar dest_port
are interpreted as the outer source/destination port for the encapsulating
UDP header.
.It Cm deletetunnel
Unconfigure the physical source and destination address for IP tunnel
interfaces previously configured with
.Cm tunnel .
.It Cm create
Create the specified network pseudo-device.
.It Cm destroy
Destroy the specified network pseudo-device.
.It Cm pltime Ar n
.Pq inet6 only
Set preferred lifetime for the address.
.It Cm prefixlen Ar n
.Pq inet and inet6 only
Effect is similar to
.Cm netmask .
but you can specify by prefix length by digits.
.It Cm deprecated
.Pq inet6 only
Set the IPv6 deprecated address bit.
.It Fl deprecated
.Pq inet6 only
Clear the IPv6 deprecated address bit.
.It Cm eui64
.Pq inet6 only
Fill interface index
.Pq lowermost 64bit of an IPv6 address
automatically.
.It Cm link[0-2]
Enable special processing of the link level of the interface.
These three options are interface specific in actual effect, however,
they are in general used to select special modes of operation.
An example
of this is to enable SLIP compression, or to select the connector type
for some Ethernet cards.
Refer to the man page for the specific driver
for more information.
.It Fl link[0-2]
Disable special processing at the link level with the specified interface.
.It Cm linkstr
Set a link-level string parameter for the interface.
This functionality varies from interface to interface.
Refer to the man page for the specific driver
for more information.
.It Fl linkstr
Remove an interface link-level string parameter.
.It Cm up
Mark an interface ``up''.
This may be used to enable an interface after an ``ifconfig down.''
It happens automatically when setting the first address on an interface.
If the interface was reset when previously marked down,
the hardware will be re-initialized.
.It Cm vhid Ar n
If the driver is a
.Xr carp 4
pseudo-device, set the virtual host ID to
.Ar n .
Acceptable values are 1 to 255.
.It Cm vlan Ar vid
If the interface is a
.Xr vlan 4
pseudo-interface, set the VLAN identifier to
.Ar vid .
These are the first 12 bits (0-4095) from a 16-bit integer used
to create an 802.1Q VLAN header for packets sent from the
.Xr vlan 4
interface.
Note that
.Cm vlan
and
.Cm vlanif
must be set at the same time.
.It Cm vlanif Ar iface
If the interface is a
.Xr vlan 4
pseudo-interface, associate the physical interface
.Ar iface
with it.
Packets transmitted through the
.Xr vlan 4
interface will be diverted to the specified physical interface
.Ar iface
with 802.1Q VLAN encapsulation.
Packets with 802.1Q encapsulation received
by the physical interface with the correct VLAN tag will be diverted to the
associated
.Xr vlan 4
pseudo-interface.
The VLAN interface is assigned a copy of the physical
interface's flags and
.Tn Ethernet
address.
If the
.Xr vlan 4
interface already has a physical interface associated with it, this command
will fail.
To change the association to another physical interface, the
existing association must be cleared first.
Note that
.Cm vlanif
and
.Cm vlan
must be set at the same time.
.It Cm -vlanif Ar iface
Dissociate
.Ar iface
from the
.Xr vlan 4
interface.
.It Cm agrport Ar iface
Add
.Ar iface
to the
.Xr agr 4
interface.
.It Cm -agrport Ar iface
Remove
.Ar iface
from the
.Xr agr 4
interface.
.It Cm vltime Ar n
.Pq inet6 only
Set valid lifetime for the address.
.It Cm ip4csum
Shorthand of
.Dq ip4csum-tx ip4csum-rx
.It Cm -ip4csum
Shorthand of
.Dq -ip4csum-tx -ip4csum-rx
.It Cm tcp4csum
Shorthand of
.Dq tcp4csum-tx tcp4csum-rx
.It Cm -tcp4csum
Shorthand of
.Dq -tcp4csum-tx -tcp4csum-rx
.It Cm udp4csum
Shorthand of
.Dq udp4csum-tx udp4csum-rx
.It Cm -udp4csum
Shorthand of
.Dq -udp4csum-tx -udp4csum-rx
.It Cm tcp6csum
Shorthand of
.Dq tcp6csum-tx tcp6csum-rx
.It Cm -tcp6csum
Shorthand of
.Dq -tcp6csum-tx -tcp6csum-rx
.It Cm udp6csum
Shorthand of
.Dq udp6csum-tx udp6csum-rx
.It Cm -udp6csum
Shorthand of
.Dq -udp6csum-tx -udp6csum-rx
.It Cm ip4csum-tx
Enable hardware-assisted IPv4 header checksums for the out-bound direction.
.It Cm -ip4csum-tx
Disable hardware-assisted IPv4 header checksums for the out-bound direction.
.It Cm ip4csum-rx
Enable hardware-assisted IPv4 header checksums for the in-bound direction.
.It Cm -ip4csum-rx
Disable hardware-assisted IPv4 header checksums for the in-bound direction.
.It Cm tcp4csum-tx
Enable hardware-assisted TCP/IPv4 checksums for the out-bound direction.
.It Cm -tcp4csum-tx
Disable hardware-assisted TCP/IPv4 checksums for the out-bound direction.
.It Cm tcp4csum-rx
Enable hardware-assisted TCP/IPv4 checksums for the in-bound direction.
.It Cm -tcp4csum-rx
Disable hardware-assisted TCP/IPv4 checksums for the in-bound direction.
.It Cm udp4csum-tx
Enable hardware-assisted UDP/IPv4 checksums for the out-bound direction.
.It Cm -udp4csum-tx
Disable hardware-assisted UDP/IPv4 checksums for the out-bound direction.
.It Cm udp4csum-rx
Enable hardware-assisted UDP/IPv4 checksums for the in-bound direction.
.It Cm -udp4csum-rx
Disable hardware-assisted UDP/IPv4 checksums for the in-bound direction.
.It Cm tcp6csum-tx
Enable hardware-assisted TCP/IPv6 checksums for the out-bound direction.
.It Cm -tcp6csum-tx
Disable hardware-assisted TCP/IPv6 checksums for the out-bound direction.
.It Cm tcp6csum-rx
Enable hardware-assisted TCP/IPv6 checksums for the in-bound direction.
.It Cm -tcp6csum-rx
Disable hardware-assisted TCP/IPv6 checksums for the in-bound direction.
.It Cm udp6csum-tx
Enable hardware-assisted UDP/IPv6 checksums for the out-bound direction.
.It Cm -udp6csum-tx
Disable hardware-assisted UDP/IPv6 checksums for the out-bound direction.
.It Cm udp6csum-rx
Enable hardware-assisted UDP/IPv6 checksums for the in-bound direction.
.It Cm -udp6csum-rx
Disable hardware-assisted UDP/IPv6 checksums for the in-bound direction.
.It Cm tso4
Enable hardware-assisted TCP/IPv4 segmentation on interfaces that
support it.
.It Cm -tso4
Disable hardware-assisted TCP/IPv4 segmentation on interfaces that
support it.
.It Cm tso6
Enable hardware-assisted TCP/IPv6 segmentation on interfaces that
support it.
.It Cm -tso6
Disable hardware-assisted TCP/IPv6 segmentation on interfaces that
support it.
.It Cm maxupd Ar n
If the driver is a
.Xr pfsync 4
pseudo-device, indicate the maximum number
of updates for a single state which can be collapsed into one.
This is an 8-bit number; the default value is 128.
.It Cm syncdev Ar iface
If the driver is a
.Xr pfsync 4
pseudo-device, use the specified interface
to send and receive pfsync state synchronisation messages.
.It Fl syncdev
If the driver is a
.Xr pfsync 4
pseudo-device, stop sending pfsync state
synchronisation messages over the network.
.It Cm syncpeer Ar peer_address
If the driver is a
.Xr pfsync 4
pseudo-device, make the pfsync link point-to-point rather than using
multicast to broadcast the state synchronisation messages.
The peer_address is the IP address of the other host taking part in
the pfsync cluster.
With this option,
.Xr pfsync 4
traffic can be protected using
.Xr ipsec 4 .
.It Fl syncpeer
If the driver is a
.Xr pfsync 4
pseudo-device, broadcast the packets using multicast.
.El
.Pp
.Nm
displays the current configuration for a network interface
when no optional parameters are supplied.
If a protocol family is specified,
.Nm
will report only the details specific to that protocol
family.
.Pp
If the
.Fl s
flag is passed before an interface name,
.Nm
will attempt to query the interface for its media status.
If the
interface supports reporting media status, and it reports that it does
not appear to be connected to a network,
.Nm
will exit with status of 1
.Pq false ;
otherwise, it will exit with a
zero
.Pq true
exit status.
Not all interface drivers support media
status reporting.
.Pp
If the
.Fl m
flag is passed before an interface name,
.Nm
will display all of the supported media for the specified interface.
If the
.Fl L
flag is supplied, address lifetime is displayed for IPv6 addresses,
as time offset string.
.Pp
Optionally, the
.Fl a
flag may be used instead of an interface name.
This flag instructs
.Nm
to display information about all interfaces in the system.
This is also the default behaviour when no arguments are given to
.Nm
on the command line.
When
.Fl a
is used, the output can be modified by adding more flags:
.Fl d
limits this to interfaces that are down,
.Fl u
limits this to interfaces that are up,
.Fl b
limits this to broadcast interfaces, and
.Fl s
omits interfaces which appear not to be connected to a network.
.Pp
The
.Fl l
flag may be used to list all available interfaces on the system, with
no other additional information.
Use of this flag is mutually exclusive
with all other flags and commands, except for
.Fl d
.Pq only list interfaces that are down ,
.Fl u
.Pq only list interfaces that are up ,
.Fl s
.Pq only list interfaces that may be connected ,
.Fl b
.Pq only list broadcast interfaces .
.Pp
The
.Fl C
flag may be used to list all of the interface cloners available on
the system, with no additional information.
Use of this flag is
mutually exclusive with all other flags and commands.
.Pp
The
.Fl v
flag prints statistics on packets sent and received on the given
interface.
If
.Fl h
is used in conjunction with
.Fl v ,
the byte statistics will be printed in "human-readable" format.
The
.Fl z
flag is identical to the
.Fl v
flag except that it zeros the interface input and output statistics
after printing them.
.Pp
The
.Fl w
flag may be used to wait
.Ar seconds
seconds for the
.Cm tentative
flag to be removed from all addresses.
0 seconds means to wait indefinitely until all addresses no longer have the
.Cm tentative
flag.
.Pp
The
.Fl N
flag is just the opposite of the
.Fl n
flag in
.Xr netstat 1
or in
.Xr route 8 :
it tells
.Nm
to try to resolve numbers to hostnames or to service names.
The default
.Nm
behavior is to print numbers instead of names.
.Pp
Only the super-user may modify the configuration of a network interface.
.Sh EXAMPLES
Add a link-layer (MAC) address to an Ethernet:
.Pp
.Ic ifconfig sip0 link 00:11:22:33:44:55
.Pp
Add and activate a link-layer (MAC) address:
.Pp
.Ic ifconfig sip0 link 00:11:22:33:44:55 active
.Sh DIAGNOSTICS
Messages indicating the specified interface does not exist, the
requested address is unknown, or the user is not privileged and
tried to alter an interface's configuration.
.Sh SEE ALSO
.Xr netstat 1 ,
.Xr agr 4 ,
.Xr carp 4 ,
.Xr ifmedia 4 ,
.Xr netintro 4 ,
.Xr pfsync 4 ,
.Xr vlan 4 ,
.Xr ifconfig.if 5 ,
.\" .Xr eon 5 ,
.Xr rc 8 ,
.Xr routed 8
.Sh HISTORY
The
.Nm
command appeared in
.Bx 4.2 .

View File

@ -1,464 +0,0 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: media.c,v 1.6 2011/08/29 14:35:00 joerg Exp $");
#endif /* not lint */
#include <assert.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <util.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_media.h>
#include <prop/proplib.h>
#include "env.h"
#include "extern.h"
#include "media.h"
#include "parse.h"
#include "util.h"
#include "prog_ops.h"
static void init_current_media(prop_dictionary_t, prop_dictionary_t);
static void media_constructor(void) __attribute__((constructor));
static int setmedia(prop_dictionary_t, prop_dictionary_t);
static int setmediainst(prop_dictionary_t, prop_dictionary_t);
static int setmediamode(prop_dictionary_t, prop_dictionary_t);
static int setmediaopt(prop_dictionary_t, prop_dictionary_t);
static int unsetmediaopt(prop_dictionary_t, prop_dictionary_t);
/*
* Media stuff. Whenever a media command is first performed, the
* currently select media is grabbed for this interface. If `media'
* is given, the current media word is modifed. `mediaopt' commands
* only modify the set and clear words. They then operate on the
* current media word later.
*/
static int media_current;
static int mediaopt_set;
static int mediaopt_clear;
static struct usage_func usage;
static const int ifm_status_valid_list[] = IFM_STATUS_VALID_LIST;
static const struct ifmedia_status_description ifm_status_descriptions[] =
IFM_STATUS_DESCRIPTIONS;
static struct pstr mediamode = PSTR_INITIALIZER1(&mediamode, "mediamode",
setmediamode, "mediamode", false, &command_root.pb_parser);
static struct pinteger mediainst = PINTEGER_INITIALIZER1(&mediainst,
"mediainst", 0, IFM_INST_MAX, 10, setmediainst, "mediainst",
&command_root.pb_parser);
static struct pstr unmediaopt = PSTR_INITIALIZER1(&unmediaopt, "-mediaopt",
unsetmediaopt, "unmediaopt", false, &command_root.pb_parser);
static struct pstr mediaopt = PSTR_INITIALIZER1(&mediaopt, "mediaopt",
setmediaopt, "mediaopt", false, &command_root.pb_parser);
static struct pstr media = PSTR_INITIALIZER1(&media, "media", setmedia, "media",
false, &command_root.pb_parser);
static const struct kwinst mediakw[] = {
{.k_word = "instance", .k_key = "anymedia", .k_type = KW_T_BOOL,
.k_bool = true, .k_act = "media", .k_deact = "mediainst",
.k_nextparser = &mediainst.pi_parser}
, {.k_word = "inst", .k_key = "anymedia", .k_type = KW_T_BOOL,
.k_bool = true, .k_act = "media", .k_deact = "mediainst",
.k_nextparser = &mediainst.pi_parser}
, {.k_word = "media", .k_key = "anymedia", .k_type = KW_T_BOOL,
.k_bool = true, .k_deact = "media", .k_altdeact = "anymedia",
.k_nextparser = &media.ps_parser}
, {.k_word = "mediaopt", .k_key = "anymedia", .k_type = KW_T_BOOL,
.k_bool = true, .k_deact = "mediaopt", .k_altdeact = "instance",
.k_nextparser = &mediaopt.ps_parser}
, {.k_word = "-mediaopt", .k_key = "anymedia", .k_type = KW_T_BOOL,
.k_bool = true, .k_deact = "unmediaopt", .k_altdeact = "media",
.k_nextparser = &unmediaopt.ps_parser}
, {.k_word = "mode", .k_key = "anymedia", .k_type = KW_T_BOOL,
.k_bool = true, .k_deact = "mode",
.k_nextparser = &mediamode.ps_parser}
};
struct pkw kwmedia = PKW_INITIALIZER(&kwmedia, "media keywords", NULL, NULL,
mediakw, __arraycount(mediakw), NULL);
__dead static void
media_error(int type, const char *val, const char *opt)
{
errx(EXIT_FAILURE, "unknown %s media %s: %s",
get_media_type_string(type), opt, val);
}
void
init_current_media(prop_dictionary_t env, prop_dictionary_t oenv)
{
const char *ifname;
struct ifmediareq ifmr;
if ((ifname = getifname(env)) == NULL)
err(EXIT_FAILURE, "getifname");
/*
* If we have not yet done so, grab the currently-selected
* media.
*/
if (prop_dictionary_get(env, "initmedia") == NULL) {
memset(&ifmr, 0, sizeof(ifmr));
if (direct_ioctl(env, SIOCGIFMEDIA, &ifmr) == -1) {
/*
* If we get E2BIG, the kernel is telling us
* that there are more, so we can ignore it.
*/
if (errno != E2BIG)
err(EXIT_FAILURE, "SIOCGIFMEDIA");
}
if (!prop_dictionary_set_bool(oenv, "initmedia", true)) {
err(EXIT_FAILURE, "%s: prop_dictionary_set_bool",
__func__);
}
media_current = ifmr.ifm_current;
}
/* Sanity. */
if (IFM_TYPE(media_current) == 0)
errx(EXIT_FAILURE, "%s: no link type?", ifname);
}
void
process_media_commands(prop_dictionary_t env)
{
struct ifreq ifr;
if (prop_dictionary_get(env, "media") == NULL &&
prop_dictionary_get(env, "mediaopt") == NULL &&
prop_dictionary_get(env, "unmediaopt") == NULL &&
prop_dictionary_get(env, "mediamode") == NULL) {
/* Nothing to do. */
return;
}
/*
* Media already set up, and commands sanity-checked. Set/clear
* any options, and we're ready to go.
*/
media_current |= mediaopt_set;
media_current &= ~mediaopt_clear;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_media = media_current;
if (direct_ioctl(env, SIOCSIFMEDIA, &ifr) == -1)
err(EXIT_FAILURE, "SIOCSIFMEDIA");
}
static int
setmedia(prop_dictionary_t env, prop_dictionary_t oenv)
{
int type, subtype, inst;
prop_data_t data;
char *val;
init_current_media(env, oenv);
data = (prop_data_t)prop_dictionary_get(env, "media");
assert(data != NULL);
/* Only one media command may be given. */
/* Must not come after mode commands */
/* Must not come after mediaopt commands */
/*
* No need to check if `instance' has been issued; setmediainst()
* craps out if `media' has not been specified.
*/
type = IFM_TYPE(media_current);
inst = IFM_INST(media_current);
val = strndup(prop_data_data_nocopy(data), prop_data_size(data));
if (val == NULL)
return -1;
/* Look up the subtype. */
subtype = get_media_subtype(type, val);
if (subtype == -1)
media_error(type, val, "subtype");
/* Build the new current media word. */
media_current = IFM_MAKEWORD(type, subtype, 0, inst);
/* Media will be set after other processing is complete. */
return 0;
}
static int
setmediaopt(prop_dictionary_t env, prop_dictionary_t oenv)
{
char *invalid;
prop_data_t data;
char *val;
init_current_media(env, oenv);
data = (prop_data_t)prop_dictionary_get(env, "mediaopt");
assert(data != NULL);
/* Can only issue `mediaopt' once. */
/* Can't issue `mediaopt' if `instance' has already been issued. */
val = strndup(prop_data_data_nocopy(data), prop_data_size(data));
if (val == NULL)
return -1;
mediaopt_set = get_media_options(media_current, val, &invalid);
free(val);
if (mediaopt_set == -1)
media_error(media_current, invalid, "option");
/* Media will be set after other processing is complete. */
return 0;
}
static int
unsetmediaopt(prop_dictionary_t env, prop_dictionary_t oenv)
{
char *invalid, *val;
prop_data_t data;
init_current_media(env, oenv);
data = (prop_data_t)prop_dictionary_get(env, "unmediaopt");
if (data == NULL) {
errno = ENOENT;
return -1;
}
val = strndup(prop_data_data_nocopy(data), prop_data_size(data));
if (val == NULL)
return -1;
/*
* No need to check for A_MEDIAINST, since the test for A_MEDIA
* implicitly checks for A_MEDIAINST.
*/
mediaopt_clear = get_media_options(media_current, val, &invalid);
free(val);
if (mediaopt_clear == -1)
media_error(media_current, invalid, "option");
/* Media will be set after other processing is complete. */
return 0;
}
static int
setmediainst(prop_dictionary_t env, prop_dictionary_t oenv)
{
int type, subtype, options;
int64_t inst;
bool rc;
init_current_media(env, oenv);
rc = prop_dictionary_get_int64(env, "mediainst", &inst);
assert(rc);
/* Can only issue `instance' once. */
/* Must have already specified `media' */
type = IFM_TYPE(media_current);
subtype = IFM_SUBTYPE(media_current);
options = IFM_OPTIONS(media_current);
media_current = IFM_MAKEWORD(type, subtype, options, inst);
/* Media will be set after other processing is complete. */
return 0;
}
static int
setmediamode(prop_dictionary_t env, prop_dictionary_t oenv)
{
int type, subtype, options, inst, mode;
prop_data_t data;
char *val;
init_current_media(env, oenv);
data = (prop_data_t)prop_dictionary_get(env, "mediamode");
assert(data != NULL);
type = IFM_TYPE(media_current);
subtype = IFM_SUBTYPE(media_current);
options = IFM_OPTIONS(media_current);
inst = IFM_INST(media_current);
val = strndup(prop_data_data_nocopy(data), prop_data_size(data));
if (val == NULL)
return -1;
mode = get_media_mode(type, val);
if (mode == -1)
media_error(type, val, "mode");
free(val);
media_current = IFM_MAKEWORD(type, subtype, options, inst) | mode;
/* Media will be set after other processing is complete. */
return 0;
}
void
print_media_word(int ifmw, const char *opt_sep)
{
const char *str;
printf("%s", get_media_subtype_string(ifmw));
/* Find mode. */
if (IFM_MODE(ifmw) != 0) {
str = get_media_mode_string(ifmw);
if (str != NULL)
printf(" mode %s", str);
}
/* Find options. */
for (; (str = get_media_option_string(&ifmw)) != NULL; opt_sep = ",")
printf("%s%s", opt_sep, str);
if (IFM_INST(ifmw) != 0)
printf(" instance %d", IFM_INST(ifmw));
}
void
media_status(prop_dictionary_t env, prop_dictionary_t oenv)
{
struct ifmediareq ifmr;
int af, i, s;
int *media_list;
const char *ifname;
if ((ifname = getifname(env)) == NULL)
err(EXIT_FAILURE, "getifname");
if ((af = getaf(env)) == -1)
af = AF_UNSPEC;
/* get out early if the family is unsupported by the kernel */
if ((s = getsock(af)) == -1)
err(EXIT_FAILURE, "%s: getsock", __func__);
memset(&ifmr, 0, sizeof(ifmr));
estrlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name));
if (prog_ioctl(s, SIOCGIFMEDIA, &ifmr) == -1) {
/*
* Interface doesn't support SIOC{G,S}IFMEDIA.
*/
return;
}
if (ifmr.ifm_count == 0) {
warnx("%s: no media types?", ifname);
return;
}
media_list = (int *)malloc(ifmr.ifm_count * sizeof(int));
if (media_list == NULL)
err(EXIT_FAILURE, "malloc");
ifmr.ifm_ulist = media_list;
if (prog_ioctl(s, SIOCGIFMEDIA, &ifmr) == -1)
err(EXIT_FAILURE, "SIOCGIFMEDIA");
printf("\tmedia: %s ", get_media_type_string(ifmr.ifm_current));
print_media_word(ifmr.ifm_current, " ");
if (ifmr.ifm_active != ifmr.ifm_current) {
printf(" (");
print_media_word(ifmr.ifm_active, " ");
printf(")");
}
printf("\n");
if (ifmr.ifm_status & IFM_STATUS_VALID) {
const struct ifmedia_status_description *ifms;
int bitno, found = 0;
printf("\tstatus: ");
for (bitno = 0; ifm_status_valid_list[bitno] != 0; bitno++) {
for (ifms = ifm_status_descriptions;
ifms->ifms_valid != 0; ifms++) {
if (ifms->ifms_type !=
IFM_TYPE(ifmr.ifm_current) ||
ifms->ifms_valid !=
ifm_status_valid_list[bitno])
continue;
printf("%s%s", found ? ", " : "",
IFM_STATUS_DESC(ifms, ifmr.ifm_status));
found = 1;
/*
* For each valid indicator bit, there's
* only one entry for each media type, so
* terminate the inner loop now.
*/
break;
}
}
if (found == 0)
printf("unknown");
printf("\n");
}
if (get_flag('m')) {
int type, printed_type;
for (type = IFM_NMIN; type <= IFM_NMAX; type += IFM_NMIN) {
for (i = 0, printed_type = 0; i < ifmr.ifm_count; i++) {
if (IFM_TYPE(media_list[i]) != type)
continue;
if (printed_type == 0) {
printf("\tsupported %s media:\n",
get_media_type_string(type));
printed_type = 1;
}
printf("\t\tmedia ");
print_media_word(media_list[i], " mediaopt ");
printf("\n");
}
}
}
free(media_list);
}
static void
media_usage(prop_dictionary_t env)
{
fprintf(stderr,
"\t[ media type ] [ mediaopt opts ] [ -mediaopt opts ] "
"[ instance minst ]\n");
}
static void
media_constructor(void)
{
if (register_flag('m') != 0)
err(EXIT_FAILURE, __func__);
usage_func_init(&usage, media_usage);
register_usage(&usage);
}

View File

@ -1,61 +0,0 @@
/* $NetBSD: prog_ops.h,v 1.3 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>
/* ifconfig is compiled outside of src/sbin/ifconfig too */
#ifndef CRUNCHOPS
struct prog_ops {
int (*op_init)(void);
int (*op_socket)(int, int, int);
int (*op_ioctl)(int, unsigned long, ...);
ssize_t (*op_read)(int, void *, size_t);
int (*op_close)(int);
};
extern const struct prog_ops prog_ops;
#define prog_init prog_ops.op_init
#define prog_socket prog_ops.op_socket
#define prog_ioctl prog_ops.op_ioctl
#define prog_read prog_ops.op_read
#define prog_close prog_ops.op_close
#else
#define prog_init ((int (*)(void))NULL)
#define prog_socket socket
#define prog_ioctl ioctl
#define prog_read read
#define prog_close close
#endif
#endif /* _PROG_OPS_H_ */

View File

@ -1,346 +0,0 @@
/* $NetBSD: util.c,v 1.17 2013/10/19 00:35:30 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: util.c,v 1.17 2013/10/19 00:35:30 christos Exp $");
#endif /* not lint */
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <netdb.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <util.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <netinet/in.h> /* XXX */
#include "env.h"
#include "extern.h"
#include "util.h"
#include "prog_ops.h"
int
getsock(int naf)
{
static int oaf = -1, s;
if (oaf == naf || (oaf != -1 && naf == AF_UNSPEC))
return s;
if (oaf != -1)
prog_close(s);
if (naf == AF_UNSPEC)
naf = AF_INET;
s = prog_socket(naf, SOCK_DGRAM, 0);
if (s == -1)
oaf = -1;
else
oaf = naf;
return s;
}
const char *
get_string(const char *val, const char *sep, u_int8_t *buf, int *lenp,
bool hexok)
{
int len;
bool hexstr;
u_int8_t *p;
len = *lenp;
p = buf;
hexstr = hexok && val[0] == '0' && tolower((u_char)val[1]) == 'x';
if (hexstr)
val += 2;
for (;;) {
if (*val == '\0')
break;
if (sep != NULL && strchr(sep, *val) != NULL) {
val++;
break;
}
if (hexstr) {
if (!isxdigit((u_char)val[0]) ||
!isxdigit((u_char)val[1])) {
warnx("bad hexadecimal digits");
return NULL;
}
}
if (p >= buf + len) {
if (hexstr)
warnx("hexadecimal digits too long");
else
warnx("strings too long");
return NULL;
}
if (hexstr) {
#define tohex(x) (isdigit(x) ? (x) - '0' : tolower(x) - 'a' + 10)
*p++ = (tohex((u_char)val[0]) << 4) |
tohex((u_char)val[1]);
#undef tohex
val += 2;
} else
*p++ = *val++;
}
len = p - buf;
if (len < *lenp)
memset(p, 0, *lenp - len);
*lenp = len;
return val;
}
void
print_string(const u_int8_t *buf, int len)
{
int i;
bool hasspc;
i = 0;
hasspc = false;
if (len < 2 || buf[0] != '0' || tolower(buf[1]) != 'x') {
for (; i < len; i++) {
if (!isprint(buf[i]))
break;
if (isspace(buf[i]))
hasspc = true;
}
}
if (i == len) {
if (hasspc || len == 0)
printf("\"%.*s\"", len, buf);
else
printf("%.*s", len, buf);
} else {
printf("0x");
for (i = 0; i < len; i++)
printf("%02x", buf[i]);
}
}
struct paddr_prefix *
prefixlen_to_mask(int af, int plen)
{
union {
struct sockaddr sa;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
} u;
struct paddr_prefix *pfx;
size_t addrlen;
uint8_t *addr;
int nbit;
memset(&u, 0, sizeof(u));
switch (af) {
case AF_INET:
addrlen = sizeof(u.sin.sin_addr);
addr = (uint8_t *)&u.sin.sin_addr;
u.sa.sa_len = sizeof(u.sin);
break;
case AF_INET6:
addrlen = sizeof(u.sin6.sin6_addr);
addr = (uint8_t *)&u.sin6.sin6_addr;
u.sa.sa_len = sizeof(u.sin6);
break;
default:
errno = EINVAL;
return NULL;
}
u.sa.sa_family = af;
if (plen < 0 || (size_t)plen > addrlen * NBBY) {
errno = EINVAL;
return NULL;
}
if (plen == 0)
plen = addrlen * NBBY;
memset(addr, 0xff, (plen + NBBY - 1) / NBBY);
nbit = plen % NBBY;
if (nbit != 0)
addr[plen / NBBY] &= ~((uint8_t)0xff >> nbit);
pfx = malloc(offsetof(struct paddr_prefix, pfx_addr) + u.sa.sa_len);
if (pfx == NULL)
return NULL;
pfx->pfx_len = plen;
memcpy(&pfx->pfx_addr, &u.sa, u.sa.sa_len);
return pfx;
}
int
direct_ioctl(prop_dictionary_t env, unsigned long cmd, void *data)
{
const char *ifname;
int s;
if ((s = getsock(AF_UNSPEC)) == -1)
err(EXIT_FAILURE, "getsock");
if ((ifname = getifname(env)) == NULL)
err(EXIT_FAILURE, "getifname");
estrlcpy(data, ifname, IFNAMSIZ);
return prog_ioctl(s, cmd, data);
}
int
indirect_ioctl(prop_dictionary_t env, unsigned long cmd, void *data)
{
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_data = data;
return direct_ioctl(env, cmd, &ifr);
}
void
print_link_addresses(prop_dictionary_t env, bool print_active_only)
{
char hbuf[NI_MAXHOST];
const char *ifname;
int s;
struct ifaddrs *ifa, *ifap;
const struct sockaddr_dl *sdl;
struct if_laddrreq iflr;
if ((ifname = getifname(env)) == NULL)
err(EXIT_FAILURE, "%s: getifname", __func__);
if ((s = getsock(AF_LINK)) == -1)
err(EXIT_FAILURE, "%s: getsock", __func__);
if (getifaddrs(&ifap) == -1)
err(EXIT_FAILURE, "%s: getifaddrs", __func__);
memset(&iflr, 0, sizeof(iflr));
strlcpy(iflr.iflr_name, ifname, sizeof(iflr.iflr_name));
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
if (strcmp(ifname, ifa->ifa_name) != 0)
continue;
if (ifa->ifa_addr->sa_family != AF_LINK)
continue;
sdl = satocsdl(ifa->ifa_addr);
memcpy(&iflr.addr, ifa->ifa_addr, MIN(ifa->ifa_addr->sa_len,
sizeof(iflr.addr)));
iflr.flags = IFLR_PREFIX;
iflr.prefixlen = sdl->sdl_alen * NBBY;
if (prog_ioctl(s, SIOCGLIFADDR, &iflr) == -1)
err(EXIT_FAILURE, "%s: ioctl", __func__);
if (((iflr.flags & IFLR_ACTIVE) != 0) != print_active_only)
continue;
if (getnameinfo(ifa->ifa_addr, ifa->ifa_addr->sa_len,
hbuf, sizeof(hbuf), NULL, 0,
Nflag ? 0 : NI_NUMERICHOST) == 0 &&
hbuf[0] != '\0') {
printf("\t%s %s\n",
print_active_only ? "address:" : "link", hbuf);
}
}
freeifaddrs(ifap);
}
int16_t
ifa_get_preference(const char *ifname, const struct sockaddr *sa)
{
struct if_addrprefreq ifap;
int s;
if ((s = getsock(sa->sa_family)) == -1) {
if (errno == EPROTONOSUPPORT)
return 0;
err(EXIT_FAILURE, "socket");
}
memset(&ifap, 0, sizeof(ifap));
estrlcpy(ifap.ifap_name, ifname, sizeof(ifap.ifap_name));
memcpy(&ifap.ifap_addr, sa, MIN(sizeof(ifap.ifap_addr), sa->sa_len));
if (prog_ioctl(s, SIOCGIFADDRPREF, &ifap) == -1) {
if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT)
return 0;
warn("SIOCGIFADDRPREF");
}
return ifap.ifap_preference;
}
void
ifa_print_preference(const char *ifname, const struct sockaddr *sa)
{
int16_t preference;
if (lflag)
return;
preference = ifa_get_preference(ifname, sa);
printf(" preference %" PRId16, preference);
}
bool
ifa_any_preferences(const char *ifname, struct ifaddrs *ifap, int family)
{
struct ifaddrs *ifa;
/* Print address preference numbers if any address has a non-zero
* preference assigned.
*/
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
if (strcmp(ifname, ifa->ifa_name) != 0)
continue;
if (ifa->ifa_addr->sa_family != family)
continue;
if (ifa_get_preference(ifa->ifa_name, ifa->ifa_addr) != 0)
return true;
}
return false;
}

View File

@ -1,190 +0,0 @@
/* $NetBSD: vlan.c,v 1.14 2014/09/15 06:46:04 ozaki-r 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: vlan.c,v 1.14 2014/09/15 06:46:04 ozaki-r Exp $");
#endif /* not lint */
#include <sys/param.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/if_ether.h>
#include <net/if_vlanvar.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 "extern.h"
#include "util.h"
static status_func_t status;
static usage_func_t usage;
static cmdloop_branch_t branch;
static void vlan_constructor(void) __attribute__((constructor));
static void vlan_status(prop_dictionary_t, prop_dictionary_t);
static int setvlan(prop_dictionary_t, prop_dictionary_t);
static int setvlanif(prop_dictionary_t, prop_dictionary_t);
struct pinteger vlantag = PINTEGER_INITIALIZER1(&vlantag, "VLAN tag",
0, USHRT_MAX, 10, setvlan, "vlantag", &command_root.pb_parser);
struct piface vlanif = PIFACE_INITIALIZER(&vlanif, "vlanif", setvlanif,
"vlanif", &command_root.pb_parser);
static const struct kwinst vlankw[] = {
{.k_word = "vlan", .k_nextparser = &vlantag.pi_parser}
, {.k_word = "vlanif", .k_act = "vlantag",
.k_nextparser = &vlanif.pif_parser}
, {.k_word = "-vlanif", .k_key = "vlanif", .k_type = KW_T_STR,
.k_str = "", .k_exec = setvlanif}
};
struct pkw vlan = PKW_INITIALIZER(&vlan, "vlan", NULL, NULL,
vlankw, __arraycount(vlankw), NULL);
static int
checkifname(prop_dictionary_t env)
{
const char *ifname;
if ((ifname = getifname(env)) == NULL)
return 1;
return strncmp(ifname, "vlan", 4) != 0 ||
!isdigit((unsigned char)ifname[4]);
}
static int
getvlan(prop_dictionary_t env, struct vlanreq *vlr, bool quiet)
{
memset(vlr, 0, sizeof(*vlr));
if (checkifname(env)) {
if (quiet)
return -1;
errx(EXIT_FAILURE, "valid only with vlan(4) interfaces");
}
if (indirect_ioctl(env, SIOCGETVLAN, vlr) == -1)
return -1;
return 0;
}
int
setvlan(prop_dictionary_t env, prop_dictionary_t oenv)
{
struct vlanreq vlr;
int64_t tag;
if (getvlan(env, &vlr, false) == -1)
err(EXIT_FAILURE, "%s: getvlan", __func__);
if (!prop_dictionary_get_int64(env, "vlantag", &tag)) {
errno = ENOENT;
return -1;
}
vlr.vlr_tag = tag;
if (indirect_ioctl(env, SIOCSETVLAN, &vlr) == -1)
err(EXIT_FAILURE, "SIOCSETVLAN");
return 0;
}
int
setvlanif(prop_dictionary_t env, prop_dictionary_t oenv)
{
struct vlanreq vlr;
const char *parent;
int64_t tag;
if (getvlan(env, &vlr, false) == -1)
err(EXIT_FAILURE, "%s: getsock", __func__);
if (!prop_dictionary_get_cstring_nocopy(env, "vlanif", &parent)) {
errno = ENOENT;
return -1;
}
strlcpy(vlr.vlr_parent, parent, sizeof(vlr.vlr_parent));
if (strcmp(parent, "") == 0)
;
else if (!prop_dictionary_get_int64(env, "vlantag", &tag)) {
errno = ENOENT;
return -1;
} else
vlr.vlr_tag = (unsigned short)tag;
if (indirect_ioctl(env, SIOCSETVLAN, &vlr) == -1)
err(EXIT_FAILURE, "SIOCSETVLAN");
return 0;
}
static void
vlan_status(prop_dictionary_t env, prop_dictionary_t oenv)
{
struct vlanreq vlr;
if (getvlan(env, &vlr, true) == -1)
return;
if (vlr.vlr_tag || vlr.vlr_parent[0] != '\0')
printf("\tvlan: %d parent: %s\n",
vlr.vlr_tag, vlr.vlr_parent[0] == '\0' ?
"<none>" : vlr.vlr_parent);
}
static void
vlan_usage(prop_dictionary_t env)
{
fprintf(stderr, "\t[ vlan n vlanif i ] [ -vlanif i ]\n");
}
static void
vlan_constructor(void)
{
cmdloop_branch_init(&branch, &vlan.pk_parser);
register_cmdloop_branch(&branch);
status_func_init(&status, vlan_status);
usage_func_init(&usage, vlan_usage);
register_status(&status);
register_usage(&usage);
}

View File

@ -1,25 +0,0 @@
# $NetBSD: Makefile,v 1.6 2013/01/21 20:28:38 christos Exp $
# From: $FreeBSD: src/sbin/newfs_msdos/Makefile,v 1.5 2001/03/26 14:33:18 ru Exp $
.include <bsd.own.mk>
PROG= newfs_msdos
MAN= newfs_msdos.8
SRCS= newfs_msdos.c partutil.c mkfs_msdos.c
LDADD+= -lutil
DPADD+= ${LIBUTIL}
LDADD+=-lprop
DPADD+=${LIBPROP}
FSCK=${NETBSDSRCDIR}/sbin/fsck
CPPFLAGS+=-I${.CURDIR} -I${FSCK}
.PATH: ${FSCK}
.if ${MACHINE} == "pc98"
CFLAGS+= -DPC98
.endif
.include <bsd.prog.mk>

View File

@ -1,997 +0,0 @@
/* $NetBSD: mkfs_msdos.c,v 1.13 2017/04/14 15:39:29 christos Exp $ */
/*
* Copyright (c) 1998 Robert Nordier
* 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(S) ``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(S) 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.
*/
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
#ifndef lint
#if 0
static const char rcsid[] =
"$FreeBSD: src/sbin/newfs_msdos/newfs_msdos.c,v 1.15 2000/10/10 01:49:37 wollman Exp $";
#else
__RCSID("$NetBSD: mkfs_msdos.c,v 1.13 2017/04/14 15:39:29 christos Exp $");
#endif
#endif /* not lint */
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/time.h>
#ifndef MAKEFS
#include <sys/mount.h>
#include <sys/disk.h>
#endif
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <signal.h>
#include <util.h>
#include <disktab.h>
#ifndef MAKEFS
#include "partutil.h"
#endif
#include "mkfs_msdos.h"
#define MAXU16 0xffff /* maximum unsigned 16-bit quantity */
#define BPN 4 /* bits per nibble */
#define NPB 2 /* nibbles per byte */
#define DOSMAGIC 0xaa55 /* DOS magic number */
#define MINBPS 512 /* minimum bytes per sector */
#define MAXSPC 128 /* maximum sectors per cluster */
#define MAXNFT 16 /* maximum number of FATs */
#define DEFBLK 4096 /* default block size */
#define DEFBLK16 2048 /* default block size FAT16 */
#define DEFRDE 512 /* default root directory entries */
#define RESFTE 2 /* reserved FAT entries */
#define MINCLS12 1 /* minimum FAT12 clusters */
#define MINCLS16 0xff5 /* minimum FAT16 clusters */
#define MINCLS32 0xfff5 /* minimum FAT32 clusters */
#define MAXCLS12 0xff4 /* maximum FAT12 clusters */
#define MAXCLS16 0xfff4 /* maximum FAT16 clusters */
#define MAXCLS32 0xffffff4 /* maximum FAT32 clusters */
#define mincls(fat_type) ((fat_type) == 12 ? MINCLS12 : \
(fat_type) == 16 ? MINCLS16 : \
MINCLS32)
#define maxcls(fat_type) ((fat_type) == 12 ? MAXCLS12 : \
(fat_type) == 16 ? MAXCLS16 : \
MAXCLS32)
#define mk1(p, x) \
(p) = (u_int8_t)(x)
#define mk2(p, x) \
(p)[0] = (u_int8_t)(x), \
(p)[1] = (u_int8_t)((x) >> 010)
#define mk4(p, x) \
(p)[0] = (u_int8_t)(x), \
(p)[1] = (u_int8_t)((x) >> 010), \
(p)[2] = (u_int8_t)((x) >> 020), \
(p)[3] = (u_int8_t)((x) >> 030)
struct bs {
u_int8_t jmp[3]; /* bootstrap entry point */
u_int8_t oem[8]; /* OEM name and version */
};
struct bsbpb {
u_int8_t bps[2]; /* bytes per sector */
u_int8_t spc; /* sectors per cluster */
u_int8_t res[2]; /* reserved sectors */
u_int8_t nft; /* number of FATs */
u_int8_t rde[2]; /* root directory entries */
u_int8_t sec[2]; /* total sectors */
u_int8_t mid; /* media descriptor */
u_int8_t spf[2]; /* sectors per FAT */
u_int8_t spt[2]; /* sectors per track */
u_int8_t hds[2]; /* drive heads */
u_int8_t hid[4]; /* hidden sectors */
u_int8_t bsec[4]; /* big total sectors */
};
struct bsxbpb {
u_int8_t bspf[4]; /* big sectors per FAT */
u_int8_t xflg[2]; /* FAT control flags */
u_int8_t vers[2]; /* file system version */
u_int8_t rdcl[4]; /* root directory start cluster */
u_int8_t infs[2]; /* file system info sector */
u_int8_t bkbs[2]; /* backup boot sector */
u_int8_t rsvd[12]; /* reserved */
};
struct bsx {
u_int8_t drv; /* drive number */
u_int8_t rsvd; /* reserved */
u_int8_t sig; /* extended boot signature */
u_int8_t volid[4]; /* volume ID number */
u_int8_t label[11]; /* volume label */
u_int8_t type[8]; /* file system type */
};
struct de {
u_int8_t namext[11]; /* name and extension */
u_int8_t attr; /* attributes */
u_int8_t rsvd[10]; /* reserved */
u_int8_t time[2]; /* creation time */
u_int8_t date[2]; /* creation date */
u_int8_t clus[2]; /* starting cluster */
u_int8_t size[4]; /* size */
};
struct bpb {
u_int bps; /* bytes per sector */
u_int spc; /* sectors per cluster */
u_int res; /* reserved sectors */
u_int nft; /* number of FATs */
u_int rde; /* root directory entries */
u_int sec; /* total sectors */
u_int mid; /* media descriptor */
u_int spf; /* sectors per FAT */
u_int spt; /* sectors per track */
u_int hds; /* drive heads */
u_int hid; /* hidden sectors */
u_int bsec; /* big total sectors */
u_int bspf; /* big sectors per FAT */
u_int rdcl; /* root directory start cluster */
u_int infs; /* file system info sector */
u_int bkbs; /* backup boot sector */
};
#define INIT(a, b, c, d, e, f, g, h, i, j) \
{ .bps = a, .spc = b, .res = c, .nft = d, .rde = e, \
.sec = f, .mid = g, .spf = h, .spt = i, .hds = j, }
static struct {
const char *name;
struct bpb bpb;
} stdfmt[] = {
{"160", INIT(512, 1, 1, 2, 64, 320, 0xfe, 1, 8, 1)},
{"180", INIT(512, 1, 1, 2, 64, 360, 0xfc, 2, 9, 1)},
{"320", INIT(512, 2, 1, 2, 112, 640, 0xff, 1, 8, 2)},
{"360", INIT(512, 2, 1, 2, 112, 720, 0xfd, 2, 9, 2)},
{"640", INIT(512, 2, 1, 2, 112, 1280, 0xfb, 2, 8, 2)},
{"720", INIT(512, 2, 1, 2, 112, 1440, 0xf9, 3, 9, 2)},
{"1200", INIT(512, 1, 1, 2, 224, 2400, 0xf9, 7, 15, 2)},
{"1232", INIT(1024,1, 1, 2, 192, 1232, 0xfe, 2, 8, 2)},
{"1440", INIT(512, 1, 1, 2, 224, 2880, 0xf0, 9, 18, 2)},
{"2880", INIT(512, 2, 1, 2, 240, 5760, 0xf0, 9, 36, 2)}
};
static u_int8_t bootcode[] = {
0xfa, /* cli */
0x31, 0xc0, /* xor ax,ax */
0x8e, 0xd0, /* mov ss,ax */
0xbc, 0x00, 0x7c, /* mov sp,7c00h */
0xfb, /* sti */
0x8e, 0xd8, /* mov ds,ax */
0xe8, 0x00, 0x00, /* call $ + 3 */
0x5e, /* pop si */
0x83, 0xc6, 0x19, /* add si,+19h */
0xbb, 0x07, 0x00, /* mov bx,0007h */
0xfc, /* cld */
0xac, /* lodsb */
0x84, 0xc0, /* test al,al */
0x74, 0x06, /* jz $ + 8 */
0xb4, 0x0e, /* mov ah,0eh */
0xcd, 0x10, /* int 10h */
0xeb, 0xf5, /* jmp $ - 9 */
0x30, 0xe4, /* xor ah,ah */
0xcd, 0x16, /* int 16h */
0xcd, 0x19, /* int 19h */
0x0d, 0x0a,
'N', 'o', 'n', '-', 's', 'y', 's', 't',
'e', 'm', ' ', 'd', 'i', 's', 'k',
0x0d, 0x0a,
'P', 'r', 'e', 's', 's', ' ', 'a', 'n',
'y', ' ', 'k', 'e', 'y', ' ', 't', 'o',
' ', 'r', 'e', 'b', 'o', 'o', 't',
0x0d, 0x0a,
0
};
static int got_siginfo = 0; /* received a SIGINFO */
#ifndef MAKEFS
static int check_mounted(const char *, mode_t);
#endif
static int getstdfmt(const char *, struct bpb *);
static int getbpbinfo(int, const char *, const char *, int, struct bpb *, off_t);
static void print_bpb(struct bpb *);
static int ckgeom(const char *, u_int, const char *);
static int oklabel(const char *);
static void mklabel(u_int8_t *, const char *);
static void setstr(u_int8_t *, const char *, size_t);
static void infohandler(int sig);
int
mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op)
{
char buf[MAXPATHLEN];
struct stat sb;
struct timeval tv;
struct bpb bpb;
struct tm *tm;
struct bs *bs;
struct bsbpb *bsbpb;
struct bsxbpb *bsxbpb;
struct bsx *bsx;
struct de *de;
u_int8_t *img;
const char *bname;
ssize_t n;
time_t now;
u_int bss, rds, cls, dir, lsn, x, x1, x2;
int ch, fd, fd1;
struct msdos_options o = *op;
int oflags = O_RDWR | O_CREAT;
if (o.block_size && o.sectors_per_cluster) {
warnx("Cannot specify both block size and sectors per cluster");
return -1;
}
if (o.OEM_string && strlen(o.OEM_string) > 8) {
warnx("%s: bad OEM string", o.OEM_string);
return -1;
}
if (o.create_size) {
if (o.no_create) {
warnx("create (-C) is incompatible with -N");
return -1;
}
if (o.offset == 0)
oflags |= O_TRUNC;
fd = open(fname, oflags, 0644);
if (fd == -1) {
warnx("failed to create %s", fname);
return -1;
}
(void)lseek(fd, o.create_size - 1, SEEK_SET);
if (write(fd, "\0", 1) != 1) {
warn("failed to set file size");
return -1;
}
(void)lseek(fd, 0, SEEK_SET);
} else if ((fd = open(fname, o.no_create ? O_RDONLY : O_RDWR)) == -1 ||
fstat(fd, &sb)) {
warn("%s", fname);
return -1;
}
#ifndef MAKEFS
if (!o.no_create)
if (check_mounted(fname, sb.st_mode) == -1)
return -1;
#endif
if (!S_ISCHR(sb.st_mode) && !o.create_size) {
warnx("warning, %s is not a character device", fname);
return -1;
}
if (o.offset && o.offset != lseek(fd, o.offset, SEEK_SET)) {
warnx("cannot seek to %jd", (intmax_t)o.offset);
return -1;
}
memset(&bpb, 0, sizeof(bpb));
if (o.floppy) {
if (getstdfmt(o.floppy, &bpb) == -1)
return -1;
bpb.bsec = bpb.sec;
bpb.sec = 0;
bpb.bspf = bpb.spf;
bpb.spf = 0;
}
if (o.drive_heads)
bpb.hds = o.drive_heads;
if (o.sectors_per_track)
bpb.spt = o.sectors_per_track;
if (o.bytes_per_sector)
bpb.bps = o.bytes_per_sector;
if (o.size)
bpb.bsec = o.size;
if (o.hidden_sectors_set)
bpb.hid = o.hidden_sectors;
if (!(o.floppy || (o.drive_heads && o.sectors_per_track &&
o.bytes_per_sector && o.size && o.hidden_sectors_set))) {
if (getbpbinfo(fd, fname, dtype, o.hidden_sectors_set, &bpb,
o.create_size) == -1)
return -1;
bpb.bsec -= (o.offset / bpb.bps);
if (bpb.spc == 0) { /* set defaults */
/* minimum cluster size */
switch (o.fat_type) {
case 12:
bpb.spc = 1; /* use 512 bytes */
x = 2; /* up to 2MB */
break;
case 16:
bpb.spc = 1; /* use 512 bytes */
x = 32; /* up to 32MB */
break;
default:
bpb.spc = 8; /* use 4k */
x = 8192; /* up to 8GB */
break;
}
x1 = howmany(bpb.bsec, (1048576 / 512)); /* -> MB */
while (bpb.spc < 128 && x < x1) {
x *= 2;
bpb.spc *= 2;
}
}
}
if (o.volume_label && !oklabel(o.volume_label)) {
warnx("%s: bad volume label", o.volume_label);
return -1;
}
switch (o.fat_type) {
case 0:
if (o.floppy)
o.fat_type = 12;
else if (!o.directory_entries && (o.info_sector || o.backup_sector))
o.fat_type = 32;
break;
case 12:
case 16:
if (o.info_sector) {
warnx("Cannot specify info sector with FAT%u", o.fat_type);
return -1;
}
if (o.backup_sector) {
warnx("Cannot specify backup sector with FAT%u", o.fat_type);
return -1;
}
break;
case 32:
if (o.directory_entries) {
warnx("Cannot specify directory entries with FAT32");
return -1;
}
break;
default:
warnx("%d: bad FAT type", o.fat_type);
return -1;
}
if (!powerof2(bpb.bps)) {
warnx("bytes/sector (%u) is not a power of 2", bpb.bps);
return -1;
}
if (bpb.bps < MINBPS) {
warnx("bytes/sector (%u) is too small; minimum is %u",
bpb.bps, MINBPS);
return -1;
}
if (o.floppy && o.fat_type == 32)
bpb.rde = 0;
if (o.block_size) {
if (!powerof2(o.block_size)) {
warnx("block size (%u) is not a power of 2", o.block_size);
return -1;
}
if (o.block_size < bpb.bps) {
warnx("block size (%u) is too small; minimum is %u",
o.block_size, bpb.bps);
return -1;
}
if (o.block_size > bpb.bps * MAXSPC) {
warnx("block size (%u) is too large; maximum is %u",
o.block_size, bpb.bps * MAXSPC);
return -1;
}
bpb.spc = o.block_size / bpb.bps;
}
if (o.sectors_per_cluster) {
if (!powerof2(o.sectors_per_cluster)) {
warnx("sectors/cluster (%u) is not a power of 2",
o.sectors_per_cluster);
return -1;
}
bpb.spc = o.sectors_per_cluster;
}
if (o.reserved_sectors)
bpb.res = o.reserved_sectors;
if (o.num_FAT) {
if (o.num_FAT > MAXNFT) {
warnx("number of FATs (%u) is too large; maximum is %u",
o.num_FAT, MAXNFT);
return -1;
}
bpb.nft = o.num_FAT;
}
if (o.directory_entries)
bpb.rde = o.directory_entries;
if (o.media_descriptor_set) {
if (o.media_descriptor < 0xf0) {
warnx("illegal media descriptor (%#x)", o.media_descriptor);
return -1;
}
bpb.mid = o.media_descriptor;
}
if (o.sectors_per_fat)
bpb.bspf = o.sectors_per_fat;
if (o.info_sector)
bpb.infs = o.info_sector;
if (o.backup_sector)
bpb.bkbs = o.backup_sector;
bss = 1;
bname = NULL;
fd1 = -1;
if (o.bootstrap) {
bname = o.bootstrap;
if (!strchr(bname, '/')) {
snprintf(buf, sizeof(buf), "/boot/%s", bname);
if (!(bname = strdup(buf))) {
warn(NULL);
return -1;
}
}
if ((fd1 = open(bname, O_RDONLY)) == -1 || fstat(fd1, &sb)) {
warn("%s", bname);
return -1;
}
if (!S_ISREG(sb.st_mode) || sb.st_size % bpb.bps ||
sb.st_size < bpb.bps || sb.st_size > bpb.bps * MAXU16) {
warnx("%s: inappropriate file type or format", bname);
return -1;
}
bss = sb.st_size / bpb.bps;
}
if (!bpb.nft)
bpb.nft = 2;
if (!o.fat_type) {
if (bpb.bsec < (bpb.res ? bpb.res : bss) +
howmany((RESFTE + (bpb.spc ? MINCLS16 : MAXCLS12 + 1)) *
((bpb.spc ? 16 : 12) / BPN), bpb.bps * NPB) *
bpb.nft +
howmany(bpb.rde ? bpb.rde : DEFRDE,
bpb.bps / sizeof(struct de)) +
(bpb.spc ? MINCLS16 : MAXCLS12 + 1) *
(bpb.spc ? bpb.spc : howmany(DEFBLK, bpb.bps)))
o.fat_type = 12;
else if (bpb.rde || bpb.bsec <
(bpb.res ? bpb.res : bss) +
howmany((RESFTE + MAXCLS16) * 2, bpb.bps) * bpb.nft +
howmany(DEFRDE, bpb.bps / sizeof(struct de)) +
(MAXCLS16 + 1) *
(bpb.spc ? bpb.spc : howmany(8192, bpb.bps)))
o.fat_type = 16;
else
o.fat_type = 32;
}
x = bss;
if (o.fat_type == 32) {
if (!bpb.infs) {
if (x == MAXU16 || x == bpb.bkbs) {
warnx("no room for info sector");
return -1;
}
bpb.infs = x;
}
if (bpb.infs != MAXU16 && x <= bpb.infs)
x = bpb.infs + 1;
if (!bpb.bkbs) {
if (x == MAXU16) {
warnx("no room for backup sector");
return -1;
}
bpb.bkbs = x;
} else if (bpb.bkbs != MAXU16 && bpb.bkbs == bpb.infs) {
warnx("backup sector would overwrite info sector");
return -1;
}
if (bpb.bkbs != MAXU16 && x <= bpb.bkbs)
x = bpb.bkbs + 1;
}
if (!bpb.res)
bpb.res = o.fat_type == 32 ? MAX(x, MAX(16384 / bpb.bps, 4)) : x;
else if (bpb.res < x) {
warnx("too few reserved sectors (need %d have %d)", x, bpb.res);
return -1;
}
if (o.fat_type != 32 && !bpb.rde)
bpb.rde = DEFRDE;
rds = howmany(bpb.rde, bpb.bps / sizeof(struct de));
if (!bpb.spc)
for (bpb.spc = howmany(o.fat_type == 16 ? DEFBLK16 : DEFBLK, bpb.bps);
bpb.spc < MAXSPC &&
bpb.res +
howmany((RESFTE + maxcls(o.fat_type)) * (o.fat_type / BPN),
bpb.bps * NPB) * bpb.nft +
rds +
(u_int64_t)(maxcls(o.fat_type) + 1) * bpb.spc <= bpb.bsec;
bpb.spc <<= 1);
if (o.fat_type != 32 && bpb.bspf > MAXU16) {
warnx("too many sectors/FAT for FAT12/16");
return -1;
}
x1 = bpb.res + rds;
x = bpb.bspf ? bpb.bspf : 1;
if (x1 + (u_int64_t)x * bpb.nft > bpb.bsec) {
warnx("meta data exceeds file system size");
return -1;
}
x1 += x * bpb.nft;
x = (u_int64_t)(bpb.bsec - x1) * bpb.bps * NPB /
(bpb.spc * bpb.bps * NPB + o.fat_type / BPN * bpb.nft);
x2 = howmany((RESFTE + MIN(x, maxcls(o.fat_type))) * (o.fat_type / BPN),
bpb.bps * NPB);
if (!bpb.bspf) {
bpb.bspf = x2;
x1 += (bpb.bspf - 1) * bpb.nft;
}
cls = (bpb.bsec - x1) / bpb.spc;
x = (u_int64_t)bpb.bspf * bpb.bps * NPB / (o.fat_type / BPN) - RESFTE;
if (cls > x)
cls = x;
if (bpb.bspf < x2) {
warnx("warning: sectors/FAT limits file system to %u clusters",
cls);
return -1;
}
if (cls < mincls(o.fat_type)) {
warnx("%u clusters too few clusters for FAT%u, need %u", cls,
o.fat_type, mincls(o.fat_type));
return -1;
}
if (cls > maxcls(o.fat_type)) {
cls = maxcls(o.fat_type);
bpb.bsec = x1 + (cls + 1) * bpb.spc - 1;
warnx("warning: FAT type limits file system to %u sectors",
bpb.bsec);
return -1;
}
printf("%s: %u sector%s in %u FAT%u cluster%s "
"(%u bytes/cluster)\n", fname, cls * bpb.spc,
cls * bpb.spc == 1 ? "" : "s", cls, o.fat_type,
cls == 1 ? "" : "s", bpb.bps * bpb.spc);
if (!bpb.mid)
bpb.mid = !bpb.hid ? 0xf0 : 0xf8;
if (o.fat_type == 32)
bpb.rdcl = RESFTE;
if (bpb.hid + bpb.bsec <= MAXU16) {
bpb.sec = bpb.bsec;
bpb.bsec = 0;
}
if (o.fat_type != 32) {
bpb.spf = bpb.bspf;
bpb.bspf = 0;
}
ch = 0;
if (o.fat_type == 12)
ch = 1; /* 001 Primary DOS with 12 bit FAT */
else if (o.fat_type == 16) {
if (bpb.bsec == 0)
ch = 4; /* 004 Primary DOS with 16 bit FAT <32M */
else
ch = 6; /* 006 Primary 'big' DOS, 16-bit FAT (> 32MB) */
/*
* XXX: what about:
* 014 DOS (16-bit FAT) - LBA
* ?
*/
} else if (o.fat_type == 32) {
ch = 11; /* 011 Primary DOS with 32 bit FAT */
/*
* XXX: what about:
* 012 Primary DOS with 32 bit FAT - LBA
* ?
*/
}
if (ch != 0)
printf("MBR type: %d\n", ch);
print_bpb(&bpb);
if (!o.no_create) {
if (o.timestamp_set) {
tv.tv_sec = now = o.timestamp;
tv.tv_usec = 0;
tm = gmtime(&now);
} else {
gettimeofday(&tv, NULL);
now = tv.tv_sec;
tm = localtime(&now);
}
if (!(img = malloc(bpb.bps)))
err(1, NULL);
dir = bpb.res + (bpb.spf ? bpb.spf : bpb.bspf) * bpb.nft;
#ifdef SIGINFO
signal(SIGINFO, infohandler);
#endif
for (lsn = 0; lsn < dir + (o.fat_type == 32 ? bpb.spc : rds); lsn++) {
if (got_siginfo) {
fprintf(stderr,"%s: writing sector %u of %u (%u%%)\n",
fname,lsn,(dir + (o.fat_type == 32 ? bpb.spc : rds)),
(lsn*100)/(dir + (o.fat_type == 32 ? bpb.spc : rds)));
got_siginfo = 0;
}
x = lsn;
if (o.bootstrap &&
o.fat_type == 32 && bpb.bkbs != MAXU16 &&
bss <= bpb.bkbs && x >= bpb.bkbs) {
x -= bpb.bkbs;
if (!x && lseek(fd1, o.offset, SEEK_SET)) {
warn("%s", bname);
return -1;
}
}
if (o.bootstrap && x < bss) {
if ((n = read(fd1, img, bpb.bps)) == -1) {
warn("%s", bname);
return -1;
}
if ((size_t)n != bpb.bps) {
warnx("%s: can't read sector %u", bname, x);
return -1;
}
} else
memset(img, 0, bpb.bps);
if (!lsn ||
(o.fat_type == 32 && bpb.bkbs != MAXU16 && lsn == bpb.bkbs)) {
x1 = sizeof(struct bs);
bsbpb = (struct bsbpb *)(img + x1);
mk2(bsbpb->bps, bpb.bps);
mk1(bsbpb->spc, bpb.spc);
mk2(bsbpb->res, bpb.res);
mk1(bsbpb->nft, bpb.nft);
mk2(bsbpb->rde, bpb.rde);
mk2(bsbpb->sec, bpb.sec);
mk1(bsbpb->mid, bpb.mid);
mk2(bsbpb->spf, bpb.spf);
mk2(bsbpb->spt, bpb.spt);
mk2(bsbpb->hds, bpb.hds);
mk4(bsbpb->hid, bpb.hid);
mk4(bsbpb->bsec, bpb.bsec);
x1 += sizeof(struct bsbpb);
if (o.fat_type == 32) {
bsxbpb = (struct bsxbpb *)(img + x1);
mk4(bsxbpb->bspf, bpb.bspf);
mk2(bsxbpb->xflg, 0);
mk2(bsxbpb->vers, 0);
mk4(bsxbpb->rdcl, bpb.rdcl);
mk2(bsxbpb->infs, bpb.infs);
mk2(bsxbpb->bkbs, bpb.bkbs);
x1 += sizeof(struct bsxbpb);
}
bsx = (struct bsx *)(img + x1);
mk1(bsx->sig, 0x29);
if (o.volume_id_set)
x = o.volume_id;
else
x = (((u_int)(1 + tm->tm_mon) << 8 |
(u_int)tm->tm_mday) +
((u_int)tm->tm_sec << 8 |
(u_int)(tv.tv_usec / 10))) << 16 |
((u_int)(1900 + tm->tm_year) +
((u_int)tm->tm_hour << 8 |
(u_int)tm->tm_min));
mk4(bsx->volid, x);
mklabel(bsx->label, o.volume_label ? o.volume_label : "NO NAME");
snprintf(buf, sizeof(buf), "FAT%u", o.fat_type);
setstr(bsx->type, buf, sizeof(bsx->type));
if (!o.bootstrap) {
x1 += sizeof(struct bsx);
bs = (struct bs *)img;
mk1(bs->jmp[0], 0xeb);
mk1(bs->jmp[1], x1 - 2);
mk1(bs->jmp[2], 0x90);
setstr(bs->oem, o.OEM_string ? o.OEM_string : "NetBSD",
sizeof(bs->oem));
memcpy(img + x1, bootcode, sizeof(bootcode));
mk2(img + MINBPS - 2, DOSMAGIC);
}
} else if (o.fat_type == 32 && bpb.infs != MAXU16 &&
(lsn == bpb.infs ||
(bpb.bkbs != MAXU16 &&
lsn == bpb.bkbs + bpb.infs))) {
mk4(img, 0x41615252);
mk4(img + MINBPS - 28, 0x61417272);
mk4(img + MINBPS - 24, 0xffffffff);
mk4(img + MINBPS - 20, 0xffffffff);
mk2(img + MINBPS - 2, DOSMAGIC);
} else if (lsn >= bpb.res && lsn < dir &&
!((lsn - bpb.res) %
(bpb.spf ? bpb.spf : bpb.bspf))) {
mk1(img[0], bpb.mid);
for (x = 1; x < o.fat_type * (o.fat_type == 32 ? 3U : 2U) / 8U; x++)
mk1(img[x], o.fat_type == 32 && x % 4 == 3 ? 0x0f : 0xff);
} else if (lsn == dir && o.volume_label) {
de = (struct de *)img;
mklabel(de->namext, o.volume_label);
mk1(de->attr, 050);
x = (u_int)tm->tm_hour << 11 |
(u_int)tm->tm_min << 5 |
(u_int)tm->tm_sec >> 1;
mk2(de->time, x);
x = (u_int)(tm->tm_year - 80) << 9 |
(u_int)(tm->tm_mon + 1) << 5 |
(u_int)tm->tm_mday;
mk2(de->date, x);
}
if ((n = write(fd, img, bpb.bps)) == -1) {
warn("%s", fname);
return -1;
}
if ((size_t)n != bpb.bps) {
warnx("%s: can't write sector %u", fname, lsn);
return -1;
}
}
}
return 0;
}
#ifndef MAKEFS
/*
* return -1 with error if file system is mounted.
*/
static int
check_mounted(const char *fname, mode_t mode)
{
struct statvfs *mp;
const char *s1, *s2;
size_t len;
int n, r;
if (!(n = getmntinfo(&mp, MNT_NOWAIT))) {
warn("getmntinfo");
return -1;
}
len = strlen(_PATH_DEV);
s1 = fname;
if (!strncmp(s1, _PATH_DEV, len))
s1 += len;
r = S_ISCHR(mode) && s1 != fname && *s1 == 'r';
for (; n--; mp++) {
s2 = mp->f_mntfromname;
if (!strncmp(s2, _PATH_DEV, len))
s2 += len;
if ((r && s2 != mp->f_mntfromname && !strcmp(s1 + 1, s2)) ||
!strcmp(s1, s2)) {
warnx("%s is mounted on %s", fname, mp->f_mntonname);
return -1;
}
}
return 0;
}
#endif
/*
* Get a standard format.
*/
static int
getstdfmt(const char *fmt, struct bpb *bpb)
{
u_int x, i;
x = sizeof(stdfmt) / sizeof(stdfmt[0]);
for (i = 0; i < x && strcmp(fmt, stdfmt[i].name); i++);
if (i == x) {
warnx("%s: unknown standard format", fmt);
return -1;
}
*bpb = stdfmt[i].bpb;
return 0;
}
/*
* Get disk slice, partition, and geometry information.
*/
static int
getbpbinfo(int fd, const char *fname, const char *dtype, int iflag,
struct bpb *bpb, off_t create_size)
{
const char *s1, *s2;
int part;
part = -1;
s1 = fname;
if ((s2 = strrchr(s1, '/')))
s1 = s2 + 1;
for (s2 = s1; *s2 && !isdigit((unsigned char)*s2); s2++);
if (!*s2 || s2 == s1)
s2 = NULL;
else
while (isdigit((unsigned char)*++s2));
s1 = s2;
#ifndef MAKEFS
int maxpartitions = getmaxpartitions();
struct disk_geom geo;
struct dkwedge_info dkw;
// XXX: Does not work with wedges
if (s2 && *s2 >= 'a' && *s2 <= 'a' + maxpartitions - 1) {
part = *s2++ - 'a';
}
#endif
if (!(((part != -1) && ((!iflag && part != -1) || !bpb->bsec)) ||
!bpb->bps || !bpb->spt || !bpb->hds)) {
return 0;
}
u_int sector_size = 512;
u_int nsectors = 63;
u_int ntracks = 255;
u_int size;
if (create_size == 0) {
#ifndef MAKEFS
if (getdiskinfo(fname, fd, NULL, &geo, &dkw) != -1) {
sector_size = geo.dg_secsize;
nsectors = geo.dg_nsectors;
ntracks = geo.dg_ntracks;
size = dkw.dkw_size;
} else
#endif
{
struct stat st;
if (fstat(fd, &st) == -1) {
warnx("Can't get disk size for `%s'", fname);
return -1;
}
size = st.st_size / sector_size;
}
} else {
size = create_size / sector_size;
}
if (!bpb->bps) {
if (ckgeom(fname, sector_size, "bytes/sector") == -1)
return -1;
bpb->bps = sector_size;
}
if (nsectors > 63) {
/*
* The kernel doesn't accept BPB with spt > 63.
* (see sys/fs/msdosfs/msdosfs_vfsops.c:msdosfs_mountfs())
* If values taken from disklabel don't match these
* restrictions, use popular BIOS default values instead.
*/
nsectors = 63;
}
if (!bpb->spt) {
if (ckgeom(fname, nsectors, "sectors/track") == -1)
return -1;
bpb->spt = nsectors;
}
if (!bpb->hds)
if (ckgeom(fname, ntracks, "drive heads") == -1)
return -1;
bpb->hds = ntracks;
if (!bpb->bsec)
bpb->bsec = size;
return 0;
}
/*
* Print out BPB values.
*/
static void
print_bpb(struct bpb *bpb)
{
printf("bps=%u spc=%u res=%u nft=%u", bpb->bps, bpb->spc, bpb->res,
bpb->nft);
if (bpb->rde)
printf(" rde=%u", bpb->rde);
if (bpb->sec)
printf(" sec=%u", bpb->sec);
printf(" mid=%#x", bpb->mid);
if (bpb->spf)
printf(" spf=%u", bpb->spf);
printf(" spt=%u hds=%u hid=%u", bpb->spt, bpb->hds, bpb->hid);
if (bpb->bsec)
printf(" bsec=%u", bpb->bsec);
if (!bpb->spf) {
printf(" bspf=%u rdcl=%u", bpb->bspf, bpb->rdcl);
printf(" infs=");
printf(bpb->infs == MAXU16 ? "%#x" : "%u", bpb->infs);
printf(" bkbs=");
printf(bpb->bkbs == MAXU16 ? "%#x" : "%u", bpb->bkbs);
}
printf("\n");
}
/*
* Check a disk geometry value.
*/
static int
ckgeom(const char *fname, u_int val, const char *msg)
{
if (!val) {
warnx("%s: no default %s", fname, msg);
return -1;
}
if (val > MAXU16) {
warnx("%s: illegal %s", fname, msg);
return -1;
}
return 0;
}
/*
* Check a volume label.
*/
static int
oklabel(const char *src)
{
int c, i;
for (i = 0; i <= 11; i++) {
c = (u_char)*src++;
if (c < ' ' + !i || strchr("\"*+,./:;<=>?[\\]|", c))
break;
}
return i && !c;
}
/*
* Make a volume label.
*/
static void
mklabel(u_int8_t *dest, const char *src)
{
int c, i;
for (i = 0; i < 11; i++) {
c = *src ? toupper((unsigned char)*src++) : ' ';
*dest++ = !i && c == '\xe5' ? 5 : c;
}
}
/*
* Copy string, padding with spaces.
*/
static void
setstr(u_int8_t *dest, const char *src, size_t len)
{
while (len--)
*dest++ = *src ? *src++ : ' ';
}
static void
infohandler(int sig)
{
got_siginfo = 1;
}

View File

@ -1,70 +0,0 @@
/* $NetBSD: mkfs_msdos.h,v 1.6 2017/02/17 09:29:35 wiz Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas.
*
* 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/types.h>
#include <stdbool.h>
#define ALLOPTS \
AOPT('@', off_t, offset, 0, "Offset in device") \
AOPT('B', char *, bootstrap, -1, "Bootstrap file") \
AOPT('C', off_t, create_size, 0, "Create file") \
AOPT('F', uint8_t, fat_type, 12, "FAT type (12, 16, or 32)") \
AOPT('I', uint32_t, volume_id, 0, "Volume ID") \
AOPT('L', char *, volume_label, -1, "Volume Label") \
AOPT('N', bool, no_create, -2, "Don't create file system, print params only") \
AOPT('O', char *, OEM_string, -1, "OEM string") \
AOPT('S', uint16_t, bytes_per_sector, 1, "Bytes per sector") \
AOPT('a', uint32_t, sectors_per_fat, 1, "Sectors per FAT") \
AOPT('b', uint32_t, block_size, 1, "Block size") \
AOPT('c', uint8_t, sectors_per_cluster, 1, "Sectors per cluster") \
AOPT('e', uint16_t, directory_entries, 1, "Directory entries") \
AOPT('f', char *, floppy, -1, "Standard format floppies (160,180,320,360,640,720,1200,1232,1440,2880)") \
AOPT('h', uint16_t, drive_heads, 1, "Drive heads") \
AOPT('i', uint16_t, info_sector, 1, "Info sector") \
AOPT('k', uint16_t, backup_sector, 1, "Backup sector") \
AOPT('m', uint8_t, media_descriptor, 0, "Media descriptor") \
AOPT('n', uint8_t, num_FAT, 1, "Number of FATs") \
AOPT('o', uint32_t, hidden_sectors, 0, "Hidden sectors") \
AOPT('r', uint16_t, reserved_sectors, 1, "Reserved sectors") \
AOPT('s', uint32_t, size, 1, "File System size") \
AOPT('u', uint16_t, sectors_per_track, 1, "Sectors per track")
struct msdos_options {
#define AOPT(_opt, _type, _name, _min, _desc) _type _name;
ALLOPTS
#undef AOPT
time_t timestamp;
uint32_t timestamp_set:1;
uint32_t volume_id_set:1;
uint32_t media_descriptor_set:1;
uint32_t hidden_sectors_set:1;
};
int mkfs_msdos(const char *, const char *, const struct msdos_options *);

View File

@ -1,253 +0,0 @@
.\" $NetBSD: newfs_msdos.8,v 1.23 2017/02/17 09:29:35 wiz Exp $
.\"
.\" Copyright (c) 1998 Robert Nordier
.\" 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(S) ``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(S) 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: $FreeBSD: src/sbin/newfs_msdos/newfs_msdos.8,v 1.13 2001/08/14 10:01:48 ru Exp $
.\"
.Dd February 16, 2017
.Dt NEWFS_MSDOS 8
.Os
.Sh NAME
.Nm newfs_msdos
.Nd construct a new MS-DOS (FAT) file system
.Sh SYNOPSIS
.Nm
.Op Fl N
.Op Fl @ Ar offset
.Op Fl B Ar boot
.Op Fl C Ar create-size
.Op Fl F Ar FAT-type
.Op Fl I Ar volid
.Op Fl L Ar label
.Op Fl O Ar OEM
.Op Fl S Ar sector-size
.Op Fl a Ar FAT-size
.Op Fl b Ar block-size
.Op Fl c Ar cluster-size
.Op Fl e Ar dirents
.Op Fl f Ar format
.Op Fl h Ar heads
.Op Fl i Ar info
.Op Fl k Ar backup
.Op Fl m Ar media
.Op Fl n Ar FATs
.Op Fl o Ar hidden
.Op Fl r Ar reserved
.Op Fl s Ar total
.Op Fl T Ar timestamp
.Op Fl u Ar track-size
.Ar special
.Op Ar disktype
.Sh DESCRIPTION
The
.Nm
utility creates a FAT12, FAT16, or FAT32 file system on device or file named
.Ar special ,
using
.Xr disktab 5
entry
.Ar disktype
to determine geometry, if required.
.Pp
The options are as follow:
.Bl -tag -width indent
.It Fl N
Do not create a file system: just print out parameters.
.It Fl @ Ar offset
Build the file system at the specified offset in bytes in the device or file.
A suffix s, k, m, g (lower or upper case)
appended to the offset specifies that the
number is in sectors, kilobytes, megabytes or gigabytes, respectively.
.It Fl B Ar boot
Get bootstrap from file.
.It Fl C Ar create-size
Create the image file with the specified size.
A suffix character appended to the size is interpreted as for the
.Fl @
option.
The file is created by truncating any existing file with the
same name, seeking just before the required size and writing
a single 0 byte.
As a consequence, the space occupied on disk
may be smaller than the size specified as a parameter.
.It Fl F Ar FAT-type
FAT type (one of 12, 16, or 32).
.It Fl I Ar volid
Volume ID.
.It Fl L Ar label
Volume label (up to 11 characters).
The label should consist of only those characters permitted
in regular DOS (8+3) filenames.
The default is
.Qq Li "NO NAME" .
.It Fl O Ar OEM
OEM string (up to 8 characters).
The default is
.Qq Li "NetBSD" .
.It Fl S Ar sector-size
Number of bytes per sector.
Acceptable values are powers of 2 in the range 512 through 32768.
.It Fl a Ar FAT-size
Number of sectors per FAT.
.It Fl b Ar block-size
File system block size (bytes per cluster).
This should resolve to an acceptable number of sectors
per cluster (see below).
.It Fl c Ar cluster-size
Sectors per cluster.
Acceptable values are powers of 2 in the range 1 through 128.
If the block or cluster size are not specified, the code
uses a cluster between 512 bytes and 32K depending on
the file system size.
.It Fl e Ar dirents
Number of root directory entries (FAT12 and FAT16 only).
.It Fl f Ar format
Specify a standard (floppy disk) format.
The standard formats are (capacities in kilobytes):
160, 180, 320, 360, 640, 720, 1200, 1232, 1440, 2880.
.It Fl h Ar heads
Number of drive heads.
.It Fl i Ar info
Location of the file system info sector (FAT32 only).
A value of 0xffff signifies no info sector.
.It Fl k Ar backup
Location of the backup boot sector (FAT32 only).
A value of 0xffff signifies no backup sector.
.It Fl m Ar media
Media descriptor (acceptable range 0xf0 to 0xff).
.It Fl n Ar FATs
Number of FATs.
Acceptable values are 1 to 16 inclusive.
The default is 2.
.It Fl o Ar hidden
Number of hidden sectors.
.It Fl r Ar reserved
Number of reserved sectors.
.It Fl s Ar total
File system size.
.It Fl T At timestamp
Specify a timestamp to be used for file system creation so that
it can be consistent for reproducible builds.
The timestamp can be a pathname, where the timestamps are derived from
that file, a parseable date for parsedate(3) (this option is not
yet available in the tools build), or an integer value interpreted
as the number of seconds from the Epoch.
.It Fl u Ar track-size
Number of sectors per track.
.El
.Pp
If
.Nm
receives a
.Dv SIGINFO
signal
(see the
.Sy status
argument for
.Xr stty 1 ) ,
a line will be written to the standard error output indicating
the name of the device currently being formatted, the sector
number being written, and the total number of sectors to be written.
.Sh NOTES
If some parameters (e.g. size, number of sectors, etc.) are not specified
through options or disktype, the program tries to generate them
automatically.
In particular, the size is determined as the
device or file size minus the offset specified with the
.Fl @
option.
When the geometry is not available, it is assumed to be
63 sectors, 255 heads.
The size is then rounded to become
a multiple of the track size and avoid complaints by some file system code.
.Pp
FAT file system parameters occupy a "Boot Sector BPB (BIOS Parameter
Block)" in the first of the "reserved" sectors which precede the actual
file system.
For reference purposes, this structure is presented below.
.Bd -literal
struct bsbpb {
u_int16_t bps; /* [-S] bytes per sector */
u_int8_t spc; /* [-c] sectors per cluster */
u_int16_t res; /* [-r] reserved sectors */
u_int8_t nft; /* [-n] number of FATs */
u_int16_t rde; /* [-e] root directory entries */
u_int16_t sec; /* [-s] total sectors */
u_int8_t mid; /* [-m] media descriptor */
u_int16_t spf; /* [-a] sectors per FAT */
u_int16_t spt; /* [-u] sectors per track */
u_int16_t hds; /* [-h] drive heads */
u_int32_t hid; /* [-o] hidden sectors */
u_int32_t bsec; /* [-s] big total sectors */
};
/* FAT32 extensions */
struct bsxbpb {
u_int32_t bspf; /* [-a] big sectors per FAT */
u_int16_t xflg; /* control flags */
u_int16_t vers; /* file system version */
u_int32_t rdcl; /* root directory start cluster */
u_int16_t infs; /* [-i] file system info sector */
u_int16_t bkbs; /* [-k] backup boot sector */
};
.Ed
.Sh EXAMPLES
.Bd -literal -offset indent
newfs_msdos /dev/rwd1a
.Ed
.Pp
Create a file system, using default parameters, on
.Pa /dev/rwd1a .
.Bd -literal -offset indent
newfs_msdos -f 1440 -L foo /dev/rfd0a
.Ed
.Pp
Create a standard 1.44M file system, with volume label
.Ar foo ,
on
.Pa /dev/rfd0a .
Create a 30MB image file, with the FAT partition starting
63 sectors within the image file:
.Bd -literal -offset indent
newfs_msdos -C 30M -@63s ./somefile
.Ed
.Sh DIAGNOSTICS
Exit status is 0 on success and 1 on error.
.Sh SEE ALSO
.Xr disktab 5 ,
.Xr disklabel 8 ,
.Xr fdisk 8 ,
.Xr newfs 8
.Sh HISTORY
A
.Nm
utility appeared in
.Fx 3.0 .
The
.Nm
command first appeared in
.Nx 1.3 .
.Sh AUTHORS
.An Robert Nordier Aq Mt rnordier@FreeBSD.org .

View File

@ -1,283 +0,0 @@
/* $NetBSD: newfs_msdos.c,v 1.45 2017/02/16 22:42:25 christos Exp $ */
/*
* Copyright (c) 1998 Robert Nordier
* 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(S) ``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(S) 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
#if 0
static const char rcsid[] =
"$FreeBSD: src/sbin/newfs_msdos/newfs_msdos.c,v 1.15 2000/10/10 01:49:37 wollman Exp $";
#else
__RCSID("$NetBSD: newfs_msdos.c,v 1.45 2017/02/16 22:42:25 christos Exp $");
#endif
#endif /* not lint */
#include <sys/param.h>
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
#include <err.h>
#include <stdlib.h>
#include <unistd.h>
#include <paths.h>
#include <errno.h>
#include <util.h>
#include "mkfs_msdos.h"
#define argto1(arg, lo, msg) argtou(arg, lo, 0xff, msg)
#define argto2(arg, lo, msg) argtou(arg, lo, 0xffff, msg)
#define argto4(arg, lo, msg) argtou(arg, lo, 0xffffffff, msg)
#define argtox(arg, lo, msg) argtou(arg, lo, UINT_MAX, msg)
__dead static void usage(void);
static u_int argtou(const char *, u_int, u_int, const char *);
static off_t argtooff(const char *, const char *);
static time_t
get_tstamp(const char *b)
{
struct stat st;
char *eb;
long long l;
#ifndef HAVE_NBTOOL_CONFIG_H
time_t when;
#endif
if (stat(b, &st) != -1)
return (time_t)st.st_mtime;
#ifndef HAVE_NBTOOL_CONFIG_H
errno = 0;
if ((when = parsedate(b, NULL, NULL)) != -1 || errno == 0)
return when;
#endif
errno = 0;
l = strtoll(b, &eb, 0);
if (b == eb || *eb || errno)
errx(EXIT_FAILURE, "Can't parse timestamp `%s'", b);
return (time_t)l;
}
/*
* Construct a FAT12, FAT16, or FAT32 file system.
*/
int
main(int argc, char *argv[])
{
static const char opts[] = "@:NB:C:F:I:L:O:S:a:b:c:e:f:h:i:k:m:n:o:r:s:T:u:";
struct msdos_options o;
char *fname, *dtype;
char buf[MAXPATHLEN];
int ch;
memset(&o, 0, sizeof(o));
while ((ch = getopt(argc, argv, opts)) != -1)
switch (ch) {
case '@':
o.offset = argtooff(optarg, "offset");
break;
case 'N':
o.no_create = 1;
break;
case 'B':
o.bootstrap = optarg;
break;
case 'C':
o.create_size = argtooff(optarg, "create size");
break;
case 'F':
o.fat_type = atoi(optarg);
break;
case 'I':
o.volume_id = argto4(optarg, 0, "volume ID");
o.volume_id_set = 1;
break;
case 'L':
o.volume_label = optarg;
break;
case 'O':
o.OEM_string = optarg;
break;
case 'S':
o.bytes_per_sector = argto2(optarg, 1, "bytes/sector");
break;
case 'a':
o.sectors_per_fat = argto4(optarg, 1, "sectors/FAT");
break;
case 'b':
o.block_size = argtox(optarg, 1, "block size");
break;
case 'c':
o.sectors_per_cluster = argto1(optarg, 1, "sectors/cluster");
break;
case 'e':
o.directory_entries = argto2(optarg, 1, "directory entries");
break;
case 'f':
o.floppy = optarg;
break;
case 'h':
o.drive_heads = argto2(optarg, 1, "drive heads");
break;
case 'i':
o.info_sector = argto2(optarg, 1, "info sector");
break;
case 'k':
o.backup_sector = argto2(optarg, 1, "backup sector");
break;
case 'm':
o.media_descriptor = argto1(optarg, 0, "media descriptor");
o.media_descriptor_set = 1;
break;
case 'n':
o.num_FAT = argto1(optarg, 1, "number of FATs");
break;
case 'o':
o.hidden_sectors = argto4(optarg, 0, "hidden sectors");
o.hidden_sectors_set = 1;
break;
case 'r':
o.reserved_sectors = argto2(optarg, 1, "reserved sectors");
break;
case 's':
o.size = argto4(optarg, 1, "file system size");
break;
case 'T':
o.timestamp_set = 1;
o.timestamp = get_tstamp(optarg);
break;
case 'u':
o.sectors_per_track = argto2(optarg, 1, "sectors/track");
break;
default:
usage();
}
argc -= optind;
argv += optind;
if (argc < 1 || argc > 2)
usage();
fname = *argv++;
if (!strchr(fname, '/') && !o.create_size) {
snprintf(buf, sizeof(buf), "%sr%s", _PATH_DEV, fname);
if (!(fname = strdup(buf)))
err(1, NULL);
}
dtype = *argv;
return mkfs_msdos(fname, dtype, &o);
}
/*
* Convert and check a numeric option argument.
*/
static u_int
argtou(const char *arg, u_int lo, u_int hi, const char *msg)
{
off_t x;
errno = 0;
x = argtooff(arg, msg);
if (x < lo || x > hi)
errx(1, "%s: bad %s", arg, msg);
return (u_int)x;
}
/*
* Same for off_t, with optional skmgpP suffix
*/
static off_t
argtooff(const char *arg, const char *msg)
{
char *s;
off_t x;
errno = 0;
x = strtoll(arg, &s, 0);
/* allow at most one extra char */
if (errno || x < 0 || (s[0] && s[1]) )
errx(1, "%s: bad %s", arg, msg);
if (*s) { /* the extra char is the multiplier */
switch (*s) {
default:
errx(1, "%s: bad %s", arg, msg);
/* notreached */
case 's': /* sector */
case 'S':
x <<= 9; /* times 512 */
break;
case 'k': /* kilobyte */
case 'K':
x <<= 10; /* times 1024 */
break;
case 'm': /* megabyte */
case 'M':
x <<= 20; /* times 1024*1024 */
break;
case 'g': /* gigabyte */
case 'G':
x <<= 30; /* times 1024*1024*1024 */
break;
case 'p': /* partition start */
case 'P': /* partition start */
case 'l': /* partition length */
case 'L': /* partition length */
errx(1, "%s: not supported yet %s", arg, msg);
return -1;
/* notreached */
}
}
return x;
}
/*
* Print usage message.
*/
static void
usage(void)
{
fprintf(stderr,
"usage: %s [ -options ] special [disktype]\n", getprogname());
fprintf(stderr, "where the options are:\n");
static struct {
char o;
const char *h;
} opts[] = {
#define AOPT(_opt, _type, _name, _min, _desc) { _opt, _desc },
ALLOPTS
#undef AOPT
};
for (size_t i = 0; i < __arraycount(opts); i++)
fprintf(stderr, "\t-%c %s\n", opts[i].o, opts[i].h);
exit(1);
}

View File

@ -1,17 +0,0 @@
# $NetBSD: Makefile,v 1.5 2014/03/18 18:20:39 riastradh Exp $
.include <bsd.own.mk>
PROG= newfs_udf
MAN= newfs_udf.8
SRCS= newfs_udf.c udf_create.c udf_write.c udf_osta.c fattr.c
MOUNT= ${NETBSDSRCDIR}/sbin/mount
KUDF= ${NETBSDSRCDIR}/sys/fs/udf
CPPFLAGS+= -I${MOUNT} -I${KUDF} -I${NETBSDSRCDIR}/sys
.PATH: ${MOUNT} ${KUDF}
DPADD+=${LIBUTIL}
LDADD+=-lutil
.include <bsd.prog.mk>

View File

@ -1,191 +0,0 @@
.\" $NetBSD: newfs_udf.8,v 1.18 2013/08/06 12:15:20 wiz Exp $
.\"
.\" Copyright (c) 2008 Reinoud Zandijk
.\" 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(S) ``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(S) 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 August 2, 2013
.Dt NEWFS_UDF 8
.Os
.Sh NAME
.Nm newfs_udf
.Nd construct a new UDF file system
.Sh SYNOPSIS
.Nm
.Op Fl cFM
.Op Fl B Ar blockingsize
.Op Fl L Ar loglabel
.Op Fl P Ar discid
.Op Fl p Ar percentage
.Op Fl S Ar sectorsize
.Op Fl s Ar size
.Op Fl t Ar gmtoff
.Op Fl V Ar max_udf
.Op Fl v Ar min_udf
.Ar special
.Sh DESCRIPTION
The
.Nm
utility creates an UDF file system on device
.Ar special
suitable for the media currently inserted.
.Pp
The options are as follow:
.Bl -tag -width indent
.It Fl B Ar blockingsize
When creating image files, specify the blocking size or packetsize of the media
to
.Ar blockingsize .
.It Fl c
Perform a crude surface check first to weed out disc faults on rewritable
media.
.It Fl F
Force file system construction on non-empty recordable media or create an
image file.
.It Fl L Ar loglabel
Set the disc logical label to the specified
.Ar loglabel .
.It Fl M
Disable metadata partition creation when selected UDF version or media dictates
this.
For strict conformance and interchange, don't disable this unless
its causing problems.
.It Fl P Ar discid
Set the physical disc label to the specified
.Ar discid .
.Pp
Prepend
.Ar discid
with volsetname separated with a ':' if wanted.
For strict conformance and interchange, don't set this manually unless it has
a unique hex number in the first 8 character positions.
.It Fl p Ar percentage
Percentage of partition to be initially reserved for metadata on the Metadata
partition.
It defaults to 20 %.
.It Fl S Ar sectorsize
Set the sectorsize for image files.
For strict conformance and interchange, don't set this manually.
.It Fl s Ar size
For image files, set the file size to the humanized size
.Ar size .
.It Fl t Ar gmtoff
Use the specified
.Ar gmtoff
as gmt time offset for recording times on the disc.
.It Fl V Ar max_udf
Select
.Ar max_udf
as the maximum UDF version to be supported.
For UDF version 2.50, use
.Dq 0x250
or
.Dq 2.50 .
.It Fl v Ar min_udf
Select
.Ar min_udf
as the minimum UDF version to be supported.
For UDF version 2.01, use
.Dq 0x201
or
.Dq 2.01 .
.El
.Sh NOTES
The UDF file system is defined for the entire optical medium.
It can only function on the entire CD/DVD/BD so the raw partition
has to be specified for read/write actions.
For
.Nm
this means specifying the raw device with the raw partition, i.e.
.Pa /dev/rcd0d
or
.Pa /dev/rcd0c .
.Pp
Some rewritable optical media needs to be formatted first before it can be
used by UDF.
This can be done using
.Xr mmcformat 8 .
.Pp
The default UDF version is version 2.01.
.Sh EXAMPLES
Create a file system, using the specified names on the device
.Pa /dev/rcd0d
with the default UDF version :
.Bd -literal -offset indent
newfs_udf -P "Encyclopedia:copy-nr-1" -L "volume 2" /dev/rcd0d
.Ed
.Pp
Create a 4.8 GiB sparse file and configure it using
.Xr vnconfig 8
to be a 2048 sector size disc and create a new UDF file system on
.Pa /dev/rvnd0d
:
.Bd -literal -offset indent
dd if=/dev/zero of=bigdisk.2048.udf seek=9999999 count=1
vnconfig -c vnd0 bigdisk.2048.udf 2048/1/1/1
newfs_udf -L bigdisk /dev/rvnd0d
.Ed
.Pp
Create a 2 GiB file and create a new UDF file system on it using the default
512 byte sector size :
.Bd -literal -offset indent
newfs_udf -L bigdisk2 -F -s 2G bigdisk2.iso
.Ed
.Pp
Create a 200 MiB file and create a new UDF file system on it using a sector size
of 2048 :
.Bd -literal -offset indent
newfs_udf -L bigdisk2 -F -s 200M -S 2048 bigdisk3.iso
.Ed
.Pp
Create a new UDF file system on the inserted USB stick using its
native sectorsize of 512 :
.Bd -literal -offset indent
newfs_udf -L "My USB stick" /dev/rsd0d
.Ed
.Sh SEE ALSO
.Xr disktab 5 ,
.Xr disklabel 8 ,
.Xr mmcformat 8 ,
.Xr newfs 8
.Sh HISTORY
The
.Nm
command first appeared in
.Nx 5.0 .
.Sh AUTHORS
.An Reinoud Zandijk Aq Mt reinoud@NetBSD.org
.Sh BUGS
The
.Ar P
and the
.Ar S
arguments have changed meaning.
The meaning of
.Ar S
has been merged into
.Ar P
since
.Nx 6.1 .

View File

@ -1,896 +0,0 @@
/* $NetBSD: newfs_udf.c,v 1.18 2013/08/09 15:11:08 reinoud Exp $ */
/*
* Copyright (c) 2006, 2008, 2013 Reinoud Zandijk
* 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.
*
*/
/*
* TODO
* - implement metadata formatting for BD-R
* - implement support for a read-only companion partition?
*/
#define _EXPOSE_MMC
#if 0
# define DEBUG
#endif
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <inttypes.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <util.h>
#include <time.h>
#include <assert.h>
#include <err.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/cdio.h>
#include <sys/disklabel.h>
#include <sys/dkio.h>
#include <sys/param.h>
#include <sys/queue.h>
#include <fs/udf/ecma167-udf.h>
#include <fs/udf/udf_mount.h>
#include "mountprog.h"
#include "udf_create.h"
#include "udf_write.h"
#include "newfs_udf.h"
/* prototypes */
int newfs_udf(int argc, char **argv);
static void usage(void) __attribute__((__noreturn__));
/* queue for temporary storage of sectors to be written out */
struct wrsect {
uint64_t sectornr;
uint8_t *sector_data;
TAILQ_ENTRY(wrsect) next;
};
/* write queue and track blocking skew */
TAILQ_HEAD(wrsect_list, wrsect) write_queue;
/* global variables describing disc and format requests */
int fd; /* device: file descriptor */
char *dev; /* device: name */
struct mmc_discinfo mmc_discinfo; /* device: disc info */
char *format_str; /* format: string representation */
int format_flags; /* format: attribute flags */
int media_accesstype; /* derived from current mmc cap */
int check_surface; /* for rewritables */
int imagefile_secsize; /* for files */
int emul_packetsize; /* for discs and files */
int wrtrack_skew;
int meta_perc = UDF_META_PERC;
float meta_fract = (float) UDF_META_PERC / 100.0;
/* --------------------------------------------------------------------- */
/*
* write queue implementation
*/
int
udf_write_sector(void *sector, uint64_t location)
{
struct wrsect *pos, *seekpos;
/* search location */
TAILQ_FOREACH_REVERSE(seekpos, &write_queue, wrsect_list, next) {
if (seekpos->sectornr <= location)
break;
}
if ((seekpos == NULL) || (seekpos->sectornr != location)) {
pos = calloc(1, sizeof(struct wrsect));
if (pos == NULL)
return ENOMEM;
/* allocate space for copy of sector data */
pos->sector_data = calloc(1, context.sector_size);
if (pos->sector_data == NULL)
return ENOMEM;
pos->sectornr = location;
if (seekpos) {
TAILQ_INSERT_AFTER(&write_queue, seekpos, pos, next);
} else {
TAILQ_INSERT_HEAD(&write_queue, pos, next);
}
} else {
pos = seekpos;
}
memcpy(pos->sector_data, sector, context.sector_size);
return 0;
}
/*
* Now all write requests are queued in the TAILQ, write them out to the
* disc/file image. Special care needs to be taken for devices that are only
* strict overwritable i.e. only in packet size chunks
*
* XXX support for growing vnd?
*/
int
writeout_write_queue(void)
{
struct wrsect *pos;
uint64_t offset;
uint64_t line_start, new_line_start;
uint32_t line_len, line_offset, relpos;
uint32_t blockingnr;
uint8_t *linebuf, *adr;
blockingnr = layout.blockingnr;
line_len = blockingnr * context.sector_size;
line_offset = wrtrack_skew * context.sector_size;
linebuf = malloc(line_len);
if (linebuf == NULL)
return ENOMEM;
pos = TAILQ_FIRST(&write_queue);
bzero(linebuf, line_len);
/*
* Always writing out in whole lines now; this is slightly wastefull
* on logical overwrite volumes but it reduces complexity and the loss
* is near zero compared to disc size.
*/
line_start = (pos->sectornr - wrtrack_skew) / blockingnr;
TAILQ_FOREACH(pos, &write_queue, next) {
new_line_start = (pos->sectornr - wrtrack_skew) / blockingnr;
if (new_line_start != line_start) {
/* write out */
offset = (uint64_t) line_start * line_len + line_offset;
#ifdef DEBUG
printf("WRITEOUT %08"PRIu64" + %02d -- "
"[%08"PRIu64"..%08"PRIu64"]\n",
offset / context.sector_size, blockingnr,
offset / context.sector_size,
offset / context.sector_size + blockingnr-1);
#endif
if (pwrite(fd, linebuf, line_len, offset) < 0) {
perror("Writing failed");
return errno;
}
line_start = new_line_start;
bzero(linebuf, line_len);
}
relpos = (pos->sectornr - wrtrack_skew) % blockingnr;
adr = linebuf + relpos * context.sector_size;
memcpy(adr, pos->sector_data, context.sector_size);
}
/* writeout last chunk */
offset = (uint64_t) line_start * line_len + line_offset;
#ifdef DEBUG
printf("WRITEOUT %08"PRIu64" + %02d -- [%08"PRIu64"..%08"PRIu64"]\n",
offset / context.sector_size, blockingnr,
offset / context.sector_size,
offset / context.sector_size + blockingnr-1);
#endif
if (pwrite(fd, linebuf, line_len, offset) < 0) {
perror("Writing failed");
return errno;
}
/* success */
return 0;
}
/* --------------------------------------------------------------------- */
/*
* mmc_discinfo and mmc_trackinfo readers modified from origional in udf main
* code in sys/fs/udf/
*/
#ifdef DEBUG
static void
udf_dump_discinfo(struct mmc_discinfo *di)
{
char bits[128];
printf("Device/media info :\n");
printf("\tMMC profile 0x%02x\n", di->mmc_profile);
printf("\tderived class %d\n", di->mmc_class);
printf("\tsector size %d\n", di->sector_size);
printf("\tdisc state %d\n", di->disc_state);
printf("\tlast ses state %d\n", di->last_session_state);
printf("\tbg format state %d\n", di->bg_format_state);
printf("\tfrst track %d\n", di->first_track);
printf("\tfst on last ses %d\n", di->first_track_last_session);
printf("\tlst on last ses %d\n", di->last_track_last_session);
printf("\tlink block penalty %d\n", di->link_block_penalty);
snprintb(bits, sizeof(bits), MMC_DFLAGS_FLAGBITS, (uint64_t) di->disc_flags);
printf("\tdisc flags %s\n", bits);
printf("\tdisc id %x\n", di->disc_id);
printf("\tdisc barcode %"PRIx64"\n", di->disc_barcode);
printf("\tnum sessions %d\n", di->num_sessions);
printf("\tnum tracks %d\n", di->num_tracks);
snprintb(bits, sizeof(bits), MMC_CAP_FLAGBITS, di->mmc_cur);
printf("\tcapabilities cur %s\n", bits);
snprintb(bits, sizeof(bits), MMC_CAP_FLAGBITS, di->mmc_cap);
printf("\tcapabilities cap %s\n", bits);
printf("\n");
printf("\tlast_possible_lba %d\n", di->last_possible_lba);
printf("\n");
}
#else
#define udf_dump_discinfo(a);
#endif
/* --------------------------------------------------------------------- */
static int
udf_update_discinfo(struct mmc_discinfo *di)
{
struct stat st;
struct disklabel disklab;
struct partition *dp;
off_t size, sectors, secsize;
int partnr, error;
memset(di, 0, sizeof(struct mmc_discinfo));
/* check if we're on a MMC capable device, i.e. CD/DVD */
error = ioctl(fd, MMCGETDISCINFO, di);
if (error == 0)
return 0;
/* (re)fstat the file */
fstat(fd, &st);
if (S_ISREG(st.st_mode)) {
/* file support; we pick the minimum sector size allowed */
size = st.st_size;
secsize = imagefile_secsize;
sectors = size / secsize;
} else {
/*
* disc partition support; note we can't use DIOCGPART in
* userland so get disc label and use the stat info to get the
* partition number.
*/
if (ioctl(fd, DIOCGDINFO, &disklab) == -1) {
/* failed to get disclabel! */
perror("disklabel");
return errno;
}
/* get disk partition it refers to */
fstat(fd, &st);
partnr = DISKPART(st.st_rdev);
dp = &disklab.d_partitions[partnr];
/* TODO problem with last_possible_lba on resizable VND */
if (dp->p_size == 0) {
perror("faulty disklabel partition returned, "
"check label\n");
return EIO;
}
sectors = dp->p_size;
secsize = disklab.d_secsize;
}
/* set up a disc info profile for partitions */
di->mmc_profile = 0x01; /* disc type */
di->mmc_class = MMC_CLASS_DISC;
di->disc_state = MMC_STATE_CLOSED;
di->last_session_state = MMC_STATE_CLOSED;
di->bg_format_state = MMC_BGFSTATE_COMPLETED;
di->link_block_penalty = 0;
di->mmc_cur = MMC_CAP_RECORDABLE | MMC_CAP_REWRITABLE |
MMC_CAP_ZEROLINKBLK | MMC_CAP_HW_DEFECTFREE;
di->mmc_cap = di->mmc_cur;
di->disc_flags = MMC_DFLAGS_UNRESTRICTED;
di->last_possible_lba = sectors - 1;
di->sector_size = secsize;
di->num_sessions = 1;
di->num_tracks = 1;
di->first_track = 1;
di->first_track_last_session = di->last_track_last_session = 1;
return 0;
}
int
udf_update_trackinfo(struct mmc_discinfo *di, struct mmc_trackinfo *ti)
{
int error, class;
class = di->mmc_class;
if (class != MMC_CLASS_DISC) {
/* tracknr specified in struct ti */
error = ioctl(fd, MMCGETTRACKINFO, ti);
return error;
}
/* discs partition support */
if (ti->tracknr != 1)
return EIO;
/* create fake ti (TODO check for resized vnds) */
ti->sessionnr = 1;
ti->track_mode = 0; /* XXX */
ti->data_mode = 0; /* XXX */
ti->flags = MMC_TRACKINFO_LRA_VALID | MMC_TRACKINFO_NWA_VALID;
ti->track_start = 0;
ti->packet_size = emul_packetsize;
/* TODO support for resizable vnd */
ti->track_size = di->last_possible_lba;
ti->next_writable = di->last_possible_lba;
ti->last_recorded = ti->next_writable;
ti->free_blocks = 0;
return 0;
}
static int
udf_setup_writeparams(struct mmc_discinfo *di)
{
struct mmc_writeparams mmc_writeparams;
int error;
if (di->mmc_class == MMC_CLASS_DISC)
return 0;
/*
* only CD burning normally needs setting up, but other disc types
* might need other settings to be made. The MMC framework will set up
* the nessisary recording parameters according to the disc
* characteristics read in. Modifications can be made in the discinfo
* structure passed to change the nature of the disc.
*/
memset(&mmc_writeparams, 0, sizeof(struct mmc_writeparams));
mmc_writeparams.mmc_class = di->mmc_class;
mmc_writeparams.mmc_cur = di->mmc_cur;
/*
* UDF dictates first track to determine track mode for the whole
* disc. [UDF 1.50/6.10.1.1, UDF 1.50/6.10.2.1]
* To prevent problems with a `reserved' track in front we start with
* the 2nd track and if that is not valid, go for the 1st.
*/
mmc_writeparams.tracknr = 2;
mmc_writeparams.data_mode = MMC_DATAMODE_DEFAULT; /* XA disc */
mmc_writeparams.track_mode = MMC_TRACKMODE_DEFAULT; /* data */
error = ioctl(fd, MMCSETUPWRITEPARAMS, &mmc_writeparams);
if (error) {
mmc_writeparams.tracknr = 1;
error = ioctl(fd, MMCSETUPWRITEPARAMS, &mmc_writeparams);
}
return error;
}
static void
udf_synchronise_caches(void)
{
struct mmc_op mmc_op;
bzero(&mmc_op, sizeof(struct mmc_op));
mmc_op.operation = MMC_OP_SYNCHRONISECACHE;
/* this device might not know this ioct, so just be ignorant */
(void) ioctl(fd, MMCOP, &mmc_op);
}
/* --------------------------------------------------------------------- */
static int
udf_prepare_disc(void)
{
struct mmc_trackinfo ti;
struct mmc_op op;
int tracknr, error;
/* If the last track is damaged, repair it */
ti.tracknr = mmc_discinfo.last_track_last_session;
error = udf_update_trackinfo(&mmc_discinfo, &ti);
if (error)
return error;
if (ti.flags & MMC_TRACKINFO_DAMAGED) {
/*
* Need to repair last track before anything can be done.
* this is an optional command, so ignore its error but report
* warning.
*/
memset(&op, 0, sizeof(op));
op.operation = MMC_OP_REPAIRTRACK;
op.mmc_profile = mmc_discinfo.mmc_profile;
op.tracknr = ti.tracknr;
error = ioctl(fd, MMCOP, &op);
if (error)
(void)printf("Drive can't explicitly repair last "
"damaged track, but it might autorepair\n");
}
/* last track (if any) might not be damaged now, operations are ok now */
/* setup write parameters from discinfo */
error = udf_setup_writeparams(&mmc_discinfo);
if (error)
return error;
/* if the drive is not sequential, we're done */
if ((mmc_discinfo.mmc_cur & MMC_CAP_SEQUENTIAL) == 0)
return 0;
#ifdef notyet
/* if last track is not the reserved but an empty track, unreserve it */
if (ti.flags & MMC_TRACKINFO_BLANK) {
if (ti.flags & MMC_TRACKINFO_RESERVED == 0) {
memset(&op, 0, sizeof(op));
op.operation = MMC_OP_UNRESERVETRACK;
op.mmc_profile = mmc_discinfo.mmc_profile;
op.tracknr = ti.tracknr;
error = ioctl(fd, MMCOP, &op);
if (error)
return error;
/* update discinfo since it changed by the operation */
error = udf_update_discinfo(&mmc_discinfo);
if (error)
return error;
}
}
#endif
/* close the last session if its still open */
if (mmc_discinfo.last_session_state == MMC_STATE_INCOMPLETE) {
printf("Closing last open session if present\n");
/* close all associated tracks */
tracknr = mmc_discinfo.first_track_last_session;
while (tracknr <= mmc_discinfo.last_track_last_session) {
ti.tracknr = tracknr;
error = udf_update_trackinfo(&mmc_discinfo, &ti);
if (error)
return error;
printf("\tClosing open track %d\n", tracknr);
memset(&op, 0, sizeof(op));
op.operation = MMC_OP_CLOSETRACK;
op.mmc_profile = mmc_discinfo.mmc_profile;
op.tracknr = tracknr;
error = ioctl(fd, MMCOP, &op);
if (error)
return error;
tracknr ++;
}
printf("Closing session\n");
memset(&op, 0, sizeof(op));
op.operation = MMC_OP_CLOSESESSION;
op.mmc_profile = mmc_discinfo.mmc_profile;
op.sessionnr = mmc_discinfo.num_sessions;
error = ioctl(fd, MMCOP, &op);
if (error)
return error;
/* update discinfo since it changed by the operations */
error = udf_update_discinfo(&mmc_discinfo);
if (error)
return error;
}
if (format_flags & FORMAT_TRACK512) {
/* get last track again */
ti.tracknr = mmc_discinfo.last_track_last_session;
error = udf_update_trackinfo(&mmc_discinfo, &ti);
if (error)
return error;
/* Split up the space at 512 for iso cd9660 hooking */
memset(&op, 0, sizeof(op));
op.operation = MMC_OP_RESERVETRACK_NWA; /* UPTO nwa */
op.mmc_profile = mmc_discinfo.mmc_profile;
op.extent = 512; /* size */
error = ioctl(fd, MMCOP, &op);
if (error)
return error;
}
return 0;
}
/* --------------------------------------------------------------------- */
int
udf_surface_check(void)
{
uint32_t loc, block_bytes;
uint32_t sector_size, blockingnr, bpos;
uint8_t *buffer;
int error, num_errors;
sector_size = context.sector_size;
blockingnr = layout.blockingnr;
block_bytes = layout.blockingnr * sector_size;
if ((buffer = malloc(block_bytes)) == NULL)
return ENOMEM;
/* set all one to not kill Flash memory? */
for (bpos = 0; bpos < block_bytes; bpos++)
buffer[bpos] = 0x00;
printf("\nChecking disc surface : phase 1 - writing\n");
num_errors = 0;
loc = layout.first_lba;
while (loc <= layout.last_lba) {
/* write blockingnr sectors */
error = pwrite(fd, buffer, block_bytes, loc*sector_size);
printf(" %08d + %d (%02d %%)\r", loc, blockingnr,
(int)((100.0 * loc)/layout.last_lba));
fflush(stdout);
if (error == -1) {
/* block is bad */
printf("BAD block at %08d + %d \n",
loc, layout.blockingnr);
if ((error = udf_register_bad_block(loc))) {
free(buffer);
return error;
}
num_errors ++;
}
loc += layout.blockingnr;
}
printf("\nChecking disc surface : phase 2 - reading\n");
num_errors = 0;
loc = layout.first_lba;
while (loc <= layout.last_lba) {
/* read blockingnr sectors */
error = pread(fd, buffer, block_bytes, loc*sector_size);
printf(" %08d + %d (%02d %%)\r", loc, blockingnr,
(int)((100.0 * loc)/layout.last_lba));
fflush(stdout);
if (error == -1) {
/* block is bad */
printf("BAD block at %08d + %d \n",
loc, layout.blockingnr);
if ((error = udf_register_bad_block(loc))) {
free(buffer);
return error;
}
num_errors ++;
}
loc += layout.blockingnr;
}
printf("Scan complete : %d bad blocks found\n", num_errors);
free(buffer);
return 0;
}
/* --------------------------------------------------------------------- */
static int
udf_do_newfs(void)
{
int error;
error = udf_do_newfs_prefix();
if (error)
return error;
error = udf_do_rootdir();
if (error)
return error;
error = udf_do_newfs_postfix();
return error;
}
/* --------------------------------------------------------------------- */
static void
usage(void)
{
(void)fprintf(stderr, "Usage: %s [-cFM] [-L loglabel] "
"[-P discid] [-S sectorsize] [-s size] [-p perc] "
"[-t gmtoff] [-v min_udf] [-V max_udf] special\n", getprogname());
exit(EXIT_FAILURE);
}
int
main(int argc, char **argv)
{
struct tm *tm;
struct stat st;
time_t now;
off_t setsize;
char scrap[255], *colon;
int ch, req_enable, req_disable, force;
int error;
setprogname(argv[0]);
/* initialise */
format_str = strdup("");
req_enable = req_disable = 0;
format_flags = FORMAT_INVALID;
force = 0;
check_surface = 0;
setsize = 0;
imagefile_secsize = 512; /* minimum allowed sector size */
emul_packetsize = 32; /* reasonable default */
srandom((unsigned long) time(NULL));
udf_init_create_context();
context.app_name = "*NetBSD newfs";
context.app_version_main = APP_VERSION_MAIN;
context.app_version_sub = APP_VERSION_SUB;
context.impl_name = IMPL_NAME;
/* minimum and maximum UDF versions we advise */
context.min_udf = 0x201;
context.max_udf = 0x201;
/* use user's time zone as default */
(void)time(&now);
tm = localtime(&now);
context.gmtoff = tm->tm_gmtoff;
/* process options */
while ((ch = getopt(argc, argv, "cFL:Mp:P:s:S:B:t:v:V:")) != -1) {
switch (ch) {
case 'c' :
check_surface = 1;
break;
case 'F' :
force = 1;
break;
case 'L' :
if (context.logvol_name) free(context.logvol_name);
context.logvol_name = strdup(optarg);
break;
case 'M' :
req_disable |= FORMAT_META;
break;
case 'p' :
meta_perc = a_num(optarg, "meta_perc");
/* limit to `sensible` values */
meta_perc = MIN(meta_perc, 99);
meta_perc = MAX(meta_perc, 1);
meta_fract = (float) meta_perc/100.0;
break;
case 'v' :
context.min_udf = a_udf_version(optarg, "min_udf");
if (context.min_udf > context.max_udf)
context.max_udf = context.min_udf;
break;
case 'V' :
context.max_udf = a_udf_version(optarg, "max_udf");
if (context.min_udf > context.max_udf)
context.min_udf = context.max_udf;
break;
case 'P' :
/* check if there is a ':' in the name */
if ((colon = strstr(optarg, ":"))) {
if (context.volset_name)
free(context.volset_name);
*colon = 0;
context.volset_name = strdup(optarg);
optarg = colon+1;
}
if (context.primary_name)
free(context.primary_name);
if ((strstr(optarg, ":"))) {
perror("primary name can't have ':' in its name");
return EXIT_FAILURE;
}
context.primary_name = strdup(optarg);
break;
case 's' :
/* support for files, set file size */
/* XXX support for formatting recordables on vnd/file? */
if (dehumanize_number(optarg, &setsize) < 0) {
perror("can't parse size argument");
return EXIT_FAILURE;
}
setsize = MAX(0, setsize);
break;
case 'S' :
imagefile_secsize = a_num(optarg, "secsize");
imagefile_secsize = MAX(512, imagefile_secsize);
break;
case 'B' :
emul_packetsize = a_num(optarg,
"blockingnr, packetsize");
emul_packetsize = MAX(emul_packetsize, 1);
emul_packetsize = MIN(emul_packetsize, 32);
break;
case 't' :
/* time zone overide */
context.gmtoff = a_num(optarg, "gmtoff");
break;
default :
usage();
/* NOTREACHED */
}
}
if (optind + 1 != argc)
usage();
/* get device and directory specifier */
dev = argv[optind];
/* open device */
if ((fd = open(dev, O_RDWR, 0)) == -1) {
/* check if we need to create a file */
fd = open(dev, O_RDONLY, 0);
if (fd > 0) {
perror("device is there but can't be opened for read/write");
return EXIT_FAILURE;
}
if (!force) {
perror("can't open device");
return EXIT_FAILURE;
}
if (setsize == 0) {
perror("need to create image file but no size specified");
return EXIT_FAILURE;
}
/* need to create a file */
fd = open(dev, O_RDWR | O_CREAT | O_TRUNC, 0777);
if (fd == -1) {
perror("can't create image file");
return EXIT_FAILURE;
}
}
/* stat the device */
if (fstat(fd, &st) != 0) {
perror("can't stat the device");
close(fd);
return EXIT_FAILURE;
}
if (S_ISREG(st.st_mode)) {
if (setsize == 0)
setsize = st.st_size;
/* sanitise arguments */
imagefile_secsize &= ~511;
setsize &= ~(imagefile_secsize-1);
if (ftruncate(fd, setsize)) {
perror("can't resize file");
return EXIT_FAILURE;
}
}
/* formatting can only be done on raw devices */
if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) {
printf("%s is not a raw device\n", dev);
close(fd);
return EXIT_FAILURE;
}
/* just in case something went wrong, synchronise the drive's cache */
udf_synchronise_caches();
/* get 'disc' information */
error = udf_update_discinfo(&mmc_discinfo);
if (error) {
perror("can't retrieve discinfo");
close(fd);
return EXIT_FAILURE;
}
/* derive disc identifiers when not specified and check given */
error = udf_proces_names();
if (error) {
/* error message has been printed */
close(fd);
return EXIT_FAILURE;
}
/* derive newfs disc format from disc profile */
error = udf_derive_format(req_enable, req_disable, force);
if (error) {
/* error message has been printed */
close(fd);
return EXIT_FAILURE;
}
udf_dump_discinfo(&mmc_discinfo);
printf("Formatting disc compatible with UDF version %x to %x\n\n",
context.min_udf, context.max_udf);
(void)snprintb(scrap, sizeof(scrap), FORMAT_FLAGBITS,
(uint64_t) format_flags);
printf("UDF properties %s\n", scrap);
printf("Volume set `%s'\n", context.volset_name);
printf("Primary volume `%s`\n", context.primary_name);
printf("Logical volume `%s`\n", context.logvol_name);
if (format_flags & FORMAT_META)
printf("Metadata percentage %d %%\n", meta_perc);
printf("\n");
/* prepare disc if nessisary (recordables mainly) */
error = udf_prepare_disc();
if (error) {
perror("preparing disc failed");
close(fd);
return EXIT_FAILURE;
};
/* setup sector writeout queue's */
TAILQ_INIT(&write_queue);
/* perform the newfs itself */
error = udf_do_newfs();
if (!error) {
/* write out sectors */
error = writeout_write_queue();
}
/* in any case, synchronise the drive's cache to prevent lockups */
udf_synchronise_caches();
close(fd);
if (error)
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
/* --------------------------------------------------------------------- */

View File

@ -1,67 +0,0 @@
/*
* Copyright (c) 2006, 2008, 2013 Reinoud Zandijk
* 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.
*
*/
#ifndef _FS_UDF_NEWFS_UDF_H_
#define _FS_UDF_NEWFS_UDF_H_
/* general settings */
#define UDF_512_TRACK 0 /* NOT recommended */
#define UDF_META_PERC 20 /* picked */
/* Identifying myself */
#define APP_VERSION_MAIN 0
#define APP_VERSION_SUB 5
#define IMPL_NAME "*NetBSD userland UDF"
/* global variables describing disc and format requests */
extern int fd; /* device: file descriptor */
extern char *dev; /* device: name */
extern struct mmc_discinfo mmc_discinfo;/* device: disc info */
extern char *format_str; /* format: string representation */
extern int format_flags; /* format: attribute flags */
extern int media_accesstype; /* derived from current mmc cap */
extern int check_surface; /* for rewritables */
extern int wrtrack_skew;
extern int meta_perc;
extern float meta_fract;
/* shared structure between udf_create.c users */
struct udf_create_context context;
struct udf_disclayout layout;
/* prototypes */
int udf_write_sector(void *sector, uint64_t location);
int udf_update_trackinfo(struct mmc_discinfo *di, struct mmc_trackinfo *ti);
/* tmp */
int writeout_write_queue(void);
int udf_surface_check(void);
#endif /* _FS_UDF_UDF_WRITE_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,283 +0,0 @@
/* $NetBSD: udf_create.h,v 1.7 2013/08/09 15:11:08 reinoud Exp $ */
/*
* Copyright (c) 2006, 2008 Reinoud Zandijk
* 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.
*
*/
#ifndef _FS_UDF_UDF_CREATE_H_
#define _FS_UDF_UDF_CREATE_H_
#include <sys/types.h>
#include <sys/stat.h>
#if !HAVE_NBTOOL_CONFIG_H
#include <fs/udf/ecma167-udf.h>
#else
#include "../../sys/fs/udf/ecma167-udf.h"
#endif
#include "udf_bswap.h"
#include "udf_osta.h"
/* format flags indicating properties of disc to create */
#define FORMAT_WRITEONCE 0x00001
#define FORMAT_SEQUENTIAL 0x00002
#define FORMAT_REWRITABLE 0x00004
#define FORMAT_SPARABLE 0x00008
#define FORMAT_META 0x00010
#define FORMAT_LOW 0x00020
#define FORMAT_VAT 0x00040
#define FORMAT_WORM 0x00080
#define FORMAT_TRACK512 0x00100
#define FORMAT_INVALID 0x00200
#define FORMAT_READONLY 0x00400
#define FORMAT_FLAGBITS \
"\10\1WRITEONCE\2SEQUENTIAL\3REWRITABLE\4SPARABLE\5META\6LOW" \
"\7VAT\10WORM\11TRACK512\12INVALID\13READONLY"
/* structure space */
#define UDF_ANCHORS 4 /* 256, 512, N-256, N */
#define UDF_PARTITIONS 4 /* overkill */
#define UDF_PMAPS 4 /* overkill */
/* misc constants */
#define UDF_MAX_NAMELEN 255 /* as per SPEC */
/* translation constants */
#define UDF_VTOP_RAWPART UDF_PMAPS /* [0..UDF_PMAPS> are normal */
/* virtual to physical mapping types */
#define UDF_VTOP_TYPE_RAW 0
#define UDF_VTOP_TYPE_UNKNOWN 0
#define UDF_VTOP_TYPE_PHYS 1
#define UDF_VTOP_TYPE_VIRT 2
#define UDF_VTOP_TYPE_SPARABLE 3
#define UDF_VTOP_TYPE_META 4
#define UDF_TRANS_ZERO ((uint64_t) -1)
#define UDF_TRANS_UNMAPPED ((uint64_t) -2)
#define UDF_TRANS_INTERN ((uint64_t) -3)
#define UDF_MAX_SECTOR ((uint64_t) -10) /* high water mark */
/* handys */
#define UDF_ROUNDUP(val, gran) \
((uint64_t) (gran) * (((uint64_t)(val) + (gran)-1) / (gran)))
#define UDF_ROUNDDOWN(val, gran) \
((uint64_t) (gran) * (((uint64_t)(val)) / (gran)))
/* disc offsets for various structures and their sizes */
struct udf_disclayout {
uint32_t wrtrack_skew;
uint32_t iso9660_vrs;
uint32_t anchors[UDF_ANCHORS];
uint32_t vds_size, vds1, vds2;
uint32_t lvis_size, lvis;
uint32_t first_lba, last_lba;
uint32_t sector_size;
uint32_t blockingnr, align_blockingnr, sparable_blockingnr;
uint32_t meta_blockingnr, meta_alignment;
/* sparables */
uint32_t sparable_blocks;
uint32_t sparable_area, sparable_area_size;
uint32_t sparing_table_dscr_lbas;
uint32_t spt_1, spt_2;
/* bitmaps */
uint32_t alloc_bitmap_dscr_size;
uint32_t unalloc_space, freed_space;
uint32_t meta_bitmap_dscr_size;
uint32_t meta_bitmap_space;
/* metadata partition */
uint32_t meta_file, meta_mirror, meta_bitmap;
uint32_t meta_part_start_lba, meta_part_size_lba;
/* main partition */
uint32_t part_start_lba, part_size_lba;
uint32_t fsd, rootdir, vat;
};
/* all info about discs and descriptors building */
struct udf_create_context {
/* descriptors */
int dscrver; /* 2 or 3 */
int min_udf; /* hex */
int max_udf; /* hex */
int serialnum; /* format serialno */
int gmtoff; /* in minutes */
/* XXX to layout? */
uint32_t sector_size;
/* identification */
char *logvol_name;
char *primary_name;
char *volset_name;
char *fileset_name;
char const *app_name;
char const *impl_name;
int app_version_main;
int app_version_sub;
/* building */
int vds_seq; /* for building functions */
int unique_id; /* only first few are used */
/* constructed structures */
struct anchor_vdp *anchors[UDF_ANCHORS]; /* anchors to VDS */
struct pri_vol_desc *primary_vol; /* identification */
struct logvol_desc *logical_vol; /* main mapping v->p */
struct unalloc_sp_desc *unallocated; /* free UDF space */
struct impvol_desc *implementation; /* likely reduntant */
struct logvol_int_desc *logvol_integrity; /* current integrity */
struct part_desc *partitions[UDF_PARTITIONS]; /* partitions */
/* XXX to layout? */
int data_part;
int metadata_part;
/* block numbers as offset in partition */
uint32_t metadata_alloc_pos;
uint32_t data_alloc_pos;
/* derived; points *into* other structures */
struct udf_logvol_info *logvol_info; /* inside integrity */
/* fileset and root directories */
struct fileset_desc *fileset_desc; /* normally one */
/* logical to physical translations */
int vtop[UDF_PMAPS+1]; /* vpartnr trans */
int vtop_tp[UDF_PMAPS+1]; /* type of trans */
uint64_t vtop_offset[UDF_PMAPS+1]; /* offset in lb */
/* sparable */
struct udf_sparing_table*sparing_table; /* replacements */
/* VAT file */
uint32_t vat_size; /* length */
uint32_t vat_allocated; /* allocated length */
uint32_t vat_start; /* offset 1st entry */
uint8_t *vat_contents; /* the VAT */
/* meta data partition */
struct extfile_entry *meta_file;
struct extfile_entry *meta_mirror;
struct extfile_entry *meta_bitmap;
/* lvint */
int num_files;
int num_directories;
uint32_t part_size[UDF_PARTITIONS];
uint32_t part_free[UDF_PARTITIONS];
struct space_bitmap_desc*part_unalloc_bits[UDF_PARTITIONS];
struct space_bitmap_desc*part_freed_bits [UDF_PARTITIONS];
};
/* globals */
extern struct udf_create_context context;
extern struct udf_disclayout layout;
/* prototypes */
void udf_init_create_context(void);
int a_udf_version(const char *s, const char *id_type);
int udf_calculate_disc_layout(int format_flags, int min_udf,
uint32_t wrtrack_skew,
uint32_t first_lba, uint32_t last_lba,
uint32_t sector_size, uint32_t blockingnr,
uint32_t sparable_blocks,
float meta_fract);
void udf_osta_charset(struct charspec *charspec);
void udf_encode_osta_id(char *osta_id, uint16_t len, char *text);
void udf_set_regid(struct regid *regid, char const *name);
void udf_add_domain_regid(struct regid *regid);
void udf_add_udf_regid(struct regid *regid);
void udf_add_impl_regid(struct regid *regid);
void udf_add_app_regid(struct regid *regid);
int udf_validate_tag_sum(union dscrptr *dscr);
int udf_validate_tag_and_crc_sums(union dscrptr *dscr);
void udf_set_timestamp_now(struct timestamp *timestamp);
void udf_inittag(struct desc_tag *tag, int tagid, uint32_t loc);
int udf_create_anchor(int num);
void udf_create_terminator(union dscrptr *dscr, uint32_t loc);
int udf_create_primaryd(void);
int udf_create_partitiond(int part_num, int part_accesstype);
int udf_create_unalloc_spaced(void);
int udf_create_sparing_tabled(void);
int udf_create_space_bitmap(uint32_t dscr_size, uint32_t part_size_lba,
struct space_bitmap_desc **sbdp);
int udf_create_logical_dscr(int format_flags);
int udf_create_impvold(char *field1, char *field2, char *field3);
int udf_create_fsd(void);
int udf_create_lvintd(int type);
void udf_update_lvintd(int type);
int udf_register_bad_block(uint32_t location);
void udf_mark_allocated(uint32_t start_lb, int partnr, uint32_t blocks);
int udf_create_new_fe(struct file_entry **fep, int file_type,
struct stat *st);
int udf_create_new_efe(struct extfile_entry **efep, int file_type,
struct stat *st);
int udf_encode_symlink(uint8_t **pathbufp, uint32_t *pathlenp, char *target);
void udf_advance_uniqueid(void);
int udf_fidsize(struct fileid_desc *fid);
void udf_create_fid(uint32_t diroff, struct fileid_desc *fid,
char *name, int namelen, struct long_ad *ref);
int udf_create_parentfid(struct fileid_desc *fid, struct long_ad *parent);
int udf_create_meta_files(void);
int udf_create_new_rootdir(union dscrptr **dscr);
int udf_create_VAT(union dscrptr **vat_dscr);
void udf_prepend_VAT_file(void);
void udf_vat_update(uint32_t virt, uint32_t phys);
int udf_append_VAT_file(void);
#endif /* _FS_UDF_UDF_CREATE_H_ */

View File

@ -1,908 +0,0 @@
/* $NetBSD: udf_write.c,v 1.9 2015/01/02 21:01:12 reinoud Exp $ */
/*
* Copyright (c) 2006, 2008, 2013 Reinoud Zandijk
* 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.
*
*/
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
__RCSID("$NetBSD: udf_write.c,v 1.9 2015/01/02 21:01:12 reinoud Exp $");
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <assert.h>
#include <err.h>
#include <sys/types.h>
#include <sys/param.h>
#if !HAVE_NBTOOL_CONFIG_H
#define _EXPOSE_MMC
#include <sys/cdio.h>
#else
#include "udf/cdio_mmc_structs.h"
#endif
#include "udf_create.h"
#include "udf_write.h"
#include "newfs_udf.h"
union dscrptr *terminator_dscr;
static int
udf_write_phys(void *blob, uint32_t location, uint32_t sects)
{
uint32_t phys, cnt;
uint8_t *bpos;
int error;
for (cnt = 0; cnt < sects; cnt++) {
bpos = (uint8_t *) blob;
bpos += context.sector_size * cnt;
phys = location + cnt;
error = udf_write_sector(bpos, phys);
if (error)
return error;
}
return 0;
}
static int
udf_write_dscr_phys(union dscrptr *dscr, uint32_t location,
uint32_t sects)
{
dscr->tag.tag_loc = udf_rw32(location);
(void) udf_validate_tag_and_crc_sums(dscr);
return udf_write_phys(dscr, location, sects);
}
int
udf_write_dscr_virt(union dscrptr *dscr, uint32_t location, uint32_t vpart,
uint32_t sects)
{
struct file_entry *fe;
struct extfile_entry *efe;
struct extattrhdr_desc *extattrhdr;
uint32_t phys;
extattrhdr = NULL;
if (udf_rw16(dscr->tag.id) == TAGID_FENTRY) {
fe = (struct file_entry *) dscr;
if (udf_rw32(fe->l_ea) > 0)
extattrhdr = (struct extattrhdr_desc *) fe->data;
}
if (udf_rw16(dscr->tag.id) == TAGID_EXTFENTRY) {
efe = (struct extfile_entry *) dscr;
if (udf_rw32(efe->l_ea) > 0)
extattrhdr = (struct extattrhdr_desc *) efe->data;
}
if (extattrhdr) {
extattrhdr->tag.tag_loc = udf_rw32(location);
udf_validate_tag_and_crc_sums((union dscrptr *) extattrhdr);
}
dscr->tag.tag_loc = udf_rw32(location);
udf_validate_tag_and_crc_sums(dscr);
/* determine physical location */
phys = context.vtop_offset[vpart];
if (context.vtop_tp[vpart] == UDF_VTOP_TYPE_VIRT) {
udf_vat_update(location, context.data_alloc_pos);
phys += context.data_alloc_pos++;
} else {
phys += location;
}
return udf_write_phys(dscr, phys, sects);
}
void
udf_metadata_alloc(int nblk, struct long_ad *pos)
{
memset(pos, 0, sizeof(*pos));
pos->len = udf_rw32(nblk * context.sector_size);
pos->loc.lb_num = udf_rw32(context.metadata_alloc_pos);
pos->loc.part_num = udf_rw16(context.metadata_part);
udf_mark_allocated(context.metadata_alloc_pos, context.metadata_part,
nblk);
context.metadata_alloc_pos += nblk;
if (context.metadata_part == context.data_part)
context.data_alloc_pos = context.metadata_alloc_pos;
}
void
udf_data_alloc(int nblk, struct long_ad *pos)
{
memset(pos, 0, sizeof(*pos));
pos->len = udf_rw32(nblk * context.sector_size);
pos->loc.lb_num = udf_rw32(context.data_alloc_pos);
pos->loc.part_num = udf_rw16(context.data_part);
udf_mark_allocated(context.data_alloc_pos, context.data_part, nblk);
context.data_alloc_pos += nblk;
if (context.metadata_part == context.data_part)
context.metadata_alloc_pos = context.data_alloc_pos;
}
/* --------------------------------------------------------------------- */
/*
* udf_derive_format derives the format_flags from the disc's mmc_discinfo.
* The resulting flags uniquely define a disc format. Note there are at least
* 7 distinct format types defined in UDF.
*/
#define UDF_VERSION(a) \
(((a) == 0x100) || ((a) == 0x102) || ((a) == 0x150) || ((a) == 0x200) || \
((a) == 0x201) || ((a) == 0x250) || ((a) == 0x260))
int
udf_derive_format(int req_enable, int req_disable, int force)
{
/* disc writability, formatted, appendable */
if ((mmc_discinfo.mmc_cur & MMC_CAP_RECORDABLE) == 0) {
(void)printf("Can't newfs readonly device\n");
return EROFS;
}
if (mmc_discinfo.mmc_cur & MMC_CAP_SEQUENTIAL) {
/* sequentials need sessions appended */
if (mmc_discinfo.disc_state == MMC_STATE_CLOSED) {
(void)printf("Can't append session to a closed disc\n");
return EROFS;
}
if ((mmc_discinfo.disc_state != MMC_STATE_EMPTY) && !force) {
(void)printf("Disc not empty! Use -F to force "
"initialisation\n");
return EROFS;
}
} else {
/* check if disc (being) formatted or has been started on */
if (mmc_discinfo.disc_state == MMC_STATE_EMPTY) {
(void)printf("Disc is not formatted\n");
return EROFS;
}
}
/* determine UDF format */
format_flags = 0;
if (mmc_discinfo.mmc_cur & MMC_CAP_REWRITABLE) {
/* all rewritable media */
format_flags |= FORMAT_REWRITABLE;
if (context.min_udf >= 0x0250) {
/* standard dictates meta as default */
format_flags |= FORMAT_META;
}
if ((mmc_discinfo.mmc_cur & MMC_CAP_HW_DEFECTFREE) == 0) {
/* sparables for defect management */
if (context.min_udf >= 0x150)
format_flags |= FORMAT_SPARABLE;
}
} else {
/* all once recordable media */
format_flags |= FORMAT_WRITEONCE;
if (mmc_discinfo.mmc_cur & MMC_CAP_SEQUENTIAL) {
format_flags |= FORMAT_SEQUENTIAL;
if (mmc_discinfo.mmc_cur & MMC_CAP_PSEUDOOVERWRITE) {
/* logical overwritable */
format_flags |= FORMAT_LOW;
} else {
/* have to use VAT for overwriting */
format_flags |= FORMAT_VAT;
}
} else {
/* rare WORM devices, but BluRay has one, strat4096 */
format_flags |= FORMAT_WORM;
}
}
/* enable/disable requests */
if (req_disable & FORMAT_META) {
format_flags &= ~(FORMAT_META | FORMAT_LOW);
req_disable &= ~FORMAT_META;
}
if ((format_flags & FORMAT_VAT) & UDF_512_TRACK)
format_flags |= FORMAT_TRACK512;
if (req_enable & FORMAT_READONLY) {
format_flags |= FORMAT_READONLY;
}
/* determine partition/media access type */
media_accesstype = UDF_ACCESSTYPE_NOT_SPECIFIED;
if (mmc_discinfo.mmc_cur & MMC_CAP_REWRITABLE) {
media_accesstype = UDF_ACCESSTYPE_OVERWRITABLE;
if (mmc_discinfo.mmc_cur & MMC_CAP_ERASABLE)
media_accesstype = UDF_ACCESSTYPE_REWRITEABLE;
} else {
/* all once recordable media */
media_accesstype = UDF_ACCESSTYPE_WRITE_ONCE;
}
if (mmc_discinfo.mmc_cur & MMC_CAP_PSEUDOOVERWRITE)
media_accesstype = UDF_ACCESSTYPE_PSEUDO_OVERWITE;
/* patch up media accesstype */
if (req_enable & FORMAT_READONLY) {
/* better now */
media_accesstype = UDF_ACCESSTYPE_READ_ONLY;
}
/* adjust minimum version limits */
if (format_flags & FORMAT_VAT)
context.min_udf = MAX(context.min_udf, 0x0150);
if (format_flags & FORMAT_SPARABLE)
context.min_udf = MAX(context.min_udf, 0x0150);
if (format_flags & FORMAT_META)
context.min_udf = MAX(context.min_udf, 0x0250);
if (format_flags & FORMAT_LOW)
context.min_udf = MAX(context.min_udf, 0x0260);
/* adjust maximum version limits not to tease or break things */
if (!(format_flags & (FORMAT_META | FORMAT_LOW)) &&
(context.max_udf > 0x200))
context.max_udf = 0x201;
if ((format_flags & (FORMAT_VAT | FORMAT_SPARABLE)) == 0)
if (context.max_udf <= 0x150)
context.min_udf = 0x102;
/* limit Ecma 167 descriptor if possible/needed */
context.dscrver = 3;
if ((context.min_udf < 0x200) || (context.max_udf < 0x200)) {
context.dscrver = 2;
context.max_udf = 0x150; /* last version < 0x200 */
}
/* is it possible ? */
if (context.min_udf > context.max_udf) {
(void)printf("Initialisation prohibited by specified maximum "
"UDF version 0x%04x. Minimum version required 0x%04x\n",
context.max_udf, context.min_udf);
return EPERM;
}
if (!UDF_VERSION(context.min_udf) || !UDF_VERSION(context.max_udf)) {
printf("Choose UDF version numbers from "
"0x102, 0x150, 0x200, 0x201, 0x250 and 0x260\n");
printf("Default version is 0x201\n");
return EPERM;
}
return 0;
}
#undef UDF_VERSION
/* --------------------------------------------------------------------- */
int
udf_proces_names(void)
{
struct timeval time_of_day;
uint32_t primary_nr;
uint64_t volset_nr;
if (context.logvol_name == NULL)
context.logvol_name = strdup("anonymous");
if (context.primary_name == NULL) {
if (mmc_discinfo.disc_flags & MMC_DFLAGS_DISCIDVALID) {
primary_nr = mmc_discinfo.disc_id;
} else {
primary_nr = (uint32_t) random();
}
context.primary_name = calloc(32, 1);
sprintf(context.primary_name, "%08"PRIx32, primary_nr);
}
if (context.volset_name == NULL) {
if (mmc_discinfo.disc_flags & MMC_DFLAGS_BARCODEVALID) {
volset_nr = mmc_discinfo.disc_barcode;
} else {
(void)gettimeofday(&time_of_day, NULL);
volset_nr = (uint64_t) random();
volset_nr |= ((uint64_t) time_of_day.tv_sec) << 32;
}
context.volset_name = calloc(128,1);
sprintf(context.volset_name, "%016"PRIx64, volset_nr);
}
if (context.fileset_name == NULL)
context.fileset_name = strdup("anonymous");
/* check passed/created identifiers */
if (strlen(context.logvol_name) > 128) {
(void)printf("Logical volume name too long\n");
return EINVAL;
}
if (strlen(context.primary_name) > 32) {
(void)printf("Primary volume name too long\n");
return EINVAL;
}
if (strlen(context.volset_name) > 128) {
(void)printf("Volume set name too long\n");
return EINVAL;
}
if (strlen(context.fileset_name) > 32) {
(void)printf("Fileset name too long\n");
return EINVAL;
}
/* signal all OK */
return 0;
}
/* --------------------------------------------------------------------- */
static int
udf_write_iso9660_vrs(void)
{
struct vrs_desc *iso9660_vrs_desc;
uint32_t pos;
int error, cnt, dpos;
/* create ISO/Ecma-167 identification descriptors */
if ((iso9660_vrs_desc = calloc(1, context.sector_size)) == NULL)
return ENOMEM;
/*
* All UDF formats should have their ISO/Ecma-167 descriptors written
* except when not possible due to track reservation in the case of
* VAT
*/
if ((format_flags & FORMAT_TRACK512) == 0) {
dpos = (2048 + context.sector_size - 1) / context.sector_size;
/* wipe at least 6 times 2048 byte `sectors' */
for (cnt = 0; cnt < 6 *dpos; cnt++) {
pos = layout.iso9660_vrs + cnt;
if ((error = udf_write_sector(iso9660_vrs_desc, pos))) {
free(iso9660_vrs_desc);
return error;
}
}
/* common VRS fields in all written out ISO descriptors */
iso9660_vrs_desc->struct_type = 0;
iso9660_vrs_desc->version = 1;
pos = layout.iso9660_vrs;
/* BEA01, NSR[23], TEA01 */
memcpy(iso9660_vrs_desc->identifier, "BEA01", 5);
if ((error = udf_write_sector(iso9660_vrs_desc, pos))) {
free(iso9660_vrs_desc);
return error;
}
pos += dpos;
if (context.dscrver == 2)
memcpy(iso9660_vrs_desc->identifier, "NSR02", 5);
else
memcpy(iso9660_vrs_desc->identifier, "NSR03", 5);
;
if ((error = udf_write_sector(iso9660_vrs_desc, pos))) {
free(iso9660_vrs_desc);
return error;
}
pos += dpos;
memcpy(iso9660_vrs_desc->identifier, "TEA01", 5);
if ((error = udf_write_sector(iso9660_vrs_desc, pos))) {
free(iso9660_vrs_desc);
return error;
}
}
free(iso9660_vrs_desc);
/* return success */
return 0;
}
/* --------------------------------------------------------------------- */
/*
* Main function that creates and writes out disc contents based on the
* format_flags's that uniquely define the type of disc to create.
*/
int
udf_do_newfs_prefix(void)
{
union dscrptr *zero_dscr;
union dscrptr *dscr;
struct mmc_trackinfo ti;
uint32_t sparable_blocks;
uint32_t sector_size, blockingnr;
uint32_t cnt, loc, len;
int sectcopy;
int error, integrity_type;
int data_part, metadata_part;
/* init */
sector_size = mmc_discinfo.sector_size;
/* determine span/size */
ti.tracknr = mmc_discinfo.first_track_last_session;
error = udf_update_trackinfo(&mmc_discinfo, &ti);
if (error)
return error;
if (mmc_discinfo.sector_size < context.sector_size) {
fprintf(stderr, "Impossible to format: sectorsize too small\n");
return EIO;
}
context.sector_size = sector_size;
/* determine blockingnr */
blockingnr = ti.packet_size;
if (blockingnr <= 1) {
/* paranoia on blockingnr */
switch (mmc_discinfo.mmc_profile) {
case 0x08 : /* CDROM */
case 0x09 : /* CD-R */
case 0x0a : /* CD-RW */
blockingnr = 32; /* UDF requirement */
break;
case 0x10 : /* DVDROM */
case 0x11 : /* DVD-R (DL) */
case 0x12 : /* DVD-RAM */
case 0x1b : /* DVD+R */
case 0x2b : /* DVD+R Dual layer */
case 0x13 : /* DVD-RW restricted overwrite */
case 0x14 : /* DVD-RW sequential */
blockingnr = 16; /* SCSI definition */
break;
case 0x40 : /* BDROM */
case 0x41 : /* BD-R Sequential recording (SRM) */
case 0x42 : /* BD-R Random recording (RRM) */
case 0x43 : /* BD-RE */
case 0x51 : /* HD DVD-R */
case 0x52 : /* HD DVD-RW */
blockingnr = 32; /* SCSI definition */
break;
default:
break;
}
}
if (blockingnr <= 0) {
printf("Can't fixup blockingnumber for device "
"type %d\n", mmc_discinfo.mmc_profile);
printf("Device is not returning valid blocking"
" number and media type is unknown.\n");
return EINVAL;
}
wrtrack_skew = ti.track_start % blockingnr;
if (mmc_discinfo.mmc_class == MMC_CLASS_CD) {
/* not too much for CD-RW, still 20MiB */
sparable_blocks = 32;
} else {
/* take a value for DVD*RW mainly, BD is `defect free' */
sparable_blocks = 512;
}
/* get layout */
error = udf_calculate_disc_layout(format_flags, context.min_udf,
wrtrack_skew,
ti.track_start, mmc_discinfo.last_possible_lba,
context.sector_size, blockingnr, sparable_blocks,
meta_fract);
/* cache partition for we need it often */
data_part = context.data_part;
metadata_part = context.metadata_part;
/* Create sparing table descriptor if applicable */
if (format_flags & FORMAT_SPARABLE) {
if ((error = udf_create_sparing_tabled()))
return error;
if (check_surface) {
if ((error = udf_surface_check()))
return error;
}
}
/* Create a generic terminator descriptor (later reused) */
terminator_dscr = calloc(1, sector_size);
if (terminator_dscr == NULL)
return ENOMEM;
udf_create_terminator(terminator_dscr, 0);
/*
* Start with wipeout of VRS1 upto start of partition. This allows
* formatting for sequentials with the track reservation and it
* cleans old rubbish on rewritables. For sequentuals without the
* track reservation all is wiped from track start.
*/
if ((zero_dscr = calloc(1, context.sector_size)) == NULL)
return ENOMEM;
loc = (format_flags & FORMAT_TRACK512) ? layout.vds1 : ti.track_start;
for (; loc < layout.part_start_lba; loc++) {
if ((error = udf_write_sector(zero_dscr, loc))) {
free(zero_dscr);
return error;
}
}
free(zero_dscr);
/* Create anchors */
for (cnt = 0; cnt < 3; cnt++) {
if ((error = udf_create_anchor(cnt))) {
return error;
}
}
/*
* Create the two Volume Descriptor Sets (VDS) each containing the
* following descriptors : primary volume, partition space,
* unallocated space, logical volume, implementation use and the
* terminator
*/
/* start of volume recognision sequence building */
context.vds_seq = 0;
/* Create primary volume descriptor */
if ((error = udf_create_primaryd()))
return error;
/* Create partition descriptor */
if ((error = udf_create_partitiond(context.data_part, media_accesstype)))
return error;
/* Create unallocated space descriptor */
if ((error = udf_create_unalloc_spaced()))
return error;
/* Create logical volume descriptor */
if ((error = udf_create_logical_dscr(format_flags)))
return error;
/* Create implementation use descriptor */
/* TODO input of fields 1,2,3 and passing them */
if ((error = udf_create_impvold(NULL, NULL, NULL)))
return error;
/* write out what we've created so far */
/* writeout iso9660 vrs */
if ((error = udf_write_iso9660_vrs()))
return error;
/* Writeout anchors */
for (cnt = 0; cnt < 3; cnt++) {
dscr = (union dscrptr *) context.anchors[cnt];
loc = layout.anchors[cnt];
if ((error = udf_write_dscr_phys(dscr, loc, 1)))
return error;
/* sequential media has only one anchor */
if (format_flags & FORMAT_SEQUENTIAL)
break;
}
/* write out main and secondary VRS */
for (sectcopy = 1; sectcopy <= 2; sectcopy++) {
loc = (sectcopy == 1) ? layout.vds1 : layout.vds2;
/* primary volume descriptor */
dscr = (union dscrptr *) context.primary_vol;
error = udf_write_dscr_phys(dscr, loc, 1);
if (error)
return error;
loc++;
/* partition descriptor(s) */
for (cnt = 0; cnt < UDF_PARTITIONS; cnt++) {
dscr = (union dscrptr *) context.partitions[cnt];
if (dscr) {
error = udf_write_dscr_phys(dscr, loc, 1);
if (error)
return error;
loc++;
}
}
/* unallocated space descriptor */
dscr = (union dscrptr *) context.unallocated;
error = udf_write_dscr_phys(dscr, loc, 1);
if (error)
return error;
loc++;
/* logical volume descriptor */
dscr = (union dscrptr *) context.logical_vol;
error = udf_write_dscr_phys(dscr, loc, 1);
if (error)
return error;
loc++;
/* implementation use descriptor */
dscr = (union dscrptr *) context.implementation;
error = udf_write_dscr_phys(dscr, loc, 1);
if (error)
return error;
loc++;
/* terminator descriptor */
error = udf_write_dscr_phys(terminator_dscr, loc, 1);
if (error)
return error;
loc++;
}
/* writeout the two sparable table descriptors (if needed) */
if (format_flags & FORMAT_SPARABLE) {
for (sectcopy = 1; sectcopy <= 2; sectcopy++) {
loc = (sectcopy == 1) ? layout.spt_1 : layout.spt_2;
dscr = (union dscrptr *) context.sparing_table;
len = layout.sparing_table_dscr_lbas;
/* writeout */
error = udf_write_dscr_phys(dscr, loc, len);
if (error)
return error;
}
}
/*
* Create unallocated space bitmap descriptor. Sequential recorded
* media report their own free/used space; no free/used space tables
* should be recorded for these.
*/
if ((format_flags & (FORMAT_SEQUENTIAL | FORMAT_READONLY)) == 0) {
error = udf_create_space_bitmap(
layout.alloc_bitmap_dscr_size,
layout.part_size_lba,
&context.part_unalloc_bits[data_part]);
if (error)
return error;
/* TODO: freed space bitmap if applicable */
/* mark space allocated for the unallocated space bitmap */
udf_mark_allocated(layout.unalloc_space, data_part,
layout.alloc_bitmap_dscr_size);
}
/*
* Create metadata partition file entries and allocate and init their
* space and free space maps.
*/
if (format_flags & FORMAT_META) {
error = udf_create_space_bitmap(
layout.meta_bitmap_dscr_size,
layout.meta_part_size_lba,
&context.part_unalloc_bits[metadata_part]);
if (error)
return error;
error = udf_create_meta_files();
if (error)
return error;
/* mark space allocated for meta partition and its bitmap */
udf_mark_allocated(layout.meta_file, data_part, 1);
udf_mark_allocated(layout.meta_mirror, data_part, 1);
udf_mark_allocated(layout.meta_bitmap, data_part, 1);
udf_mark_allocated(layout.meta_part_start_lba, data_part,
layout.meta_part_size_lba);
/* mark space allocated for the unallocated space bitmap */
udf_mark_allocated(layout.meta_bitmap_space, data_part,
layout.meta_bitmap_dscr_size);
}
/* create logical volume integrity descriptor */
context.num_files = 0;
context.num_directories = 0;
integrity_type = UDF_INTEGRITY_OPEN;
if ((error = udf_create_lvintd(integrity_type)))
return error;
/* writeout initial open integrity sequence + terminator */
loc = layout.lvis;
dscr = (union dscrptr *) context.logvol_integrity;
error = udf_write_dscr_phys(dscr, loc, 1);
if (error)
return error;
loc++;
error = udf_write_dscr_phys(terminator_dscr, loc, 1);
if (error)
return error;
/* create VAT if needed */
if (format_flags & FORMAT_VAT) {
context.vat_allocated = context.sector_size;
context.vat_contents = malloc(context.vat_allocated);
assert(context.vat_contents);
udf_prepend_VAT_file();
}
/* create FSD and writeout */
if ((error = udf_create_fsd()))
return error;
udf_mark_allocated(layout.fsd, metadata_part, 1);
dscr = (union dscrptr *) context.fileset_desc;
error = udf_write_dscr_virt(dscr, layout.fsd, metadata_part, 1);
return error;
}
/* specific routine for newfs to create empty rootdirectory */
int
udf_do_rootdir(void) {
union dscrptr *root_dscr;
int error;
/* create root directory and write out */
assert(context.unique_id == 0x10);
context.unique_id = 0;
if ((error = udf_create_new_rootdir(&root_dscr)))
return error;
udf_mark_allocated(layout.rootdir, context.metadata_part, 1);
error = udf_write_dscr_virt(root_dscr,
layout.rootdir, context.metadata_part, 1);
free(root_dscr);
return error;
}
int
udf_do_newfs_postfix(void)
{
union dscrptr *vat_dscr;
union dscrptr *dscr;
struct long_ad vatdata_pos;
uint32_t loc, len, phys, sects;
int data_part, metadata_part;
int error;
/* cache partition for we need it often */
data_part = context.data_part;
metadata_part = context.metadata_part;
if ((format_flags & FORMAT_SEQUENTIAL) == 0) {
/* update lvint and mark it closed */
udf_update_lvintd(UDF_INTEGRITY_CLOSED);
/* overwrite initial terminator */
loc = layout.lvis+1;
dscr = (union dscrptr *) context.logvol_integrity;
error = udf_write_dscr_phys(dscr, loc, 1);
if (error)
return error;
loc++;
/* mark end of integrity desciptor sequence again */
error = udf_write_dscr_phys(terminator_dscr, loc, 1);
if (error)
return error;
}
/* write out unallocated space bitmap on non sequential media */
if ((format_flags & (FORMAT_SEQUENTIAL | FORMAT_READONLY)) == 0) {
/* writeout unallocated space bitmap */
loc = layout.unalloc_space;
dscr = (union dscrptr *) (context.part_unalloc_bits[data_part]);
len = layout.alloc_bitmap_dscr_size;
error = udf_write_dscr_virt(dscr, loc, data_part, len);
if (error)
return error;
}
if (format_flags & FORMAT_META) {
loc = layout.meta_file;
dscr = (union dscrptr *) context.meta_file;
error = udf_write_dscr_virt(dscr, loc, data_part, 1);
if (error)
return error;
loc = layout.meta_mirror;
dscr = (union dscrptr *) context.meta_mirror;
error = udf_write_dscr_virt(dscr, loc, data_part, 1);
if (error)
return error;
loc = layout.meta_bitmap;
dscr = (union dscrptr *) context.meta_bitmap;
error = udf_write_dscr_virt(dscr, loc, data_part, 1);
if (error)
return error;
/* writeout unallocated space bitmap */
loc = layout.meta_bitmap_space;
dscr = (union dscrptr *)
(context.part_unalloc_bits[metadata_part]);
len = layout.meta_bitmap_dscr_size;
error = udf_write_dscr_virt(dscr, loc, data_part, len);
if (error)
return error;
}
/* create a VAT and account for FSD+root */
vat_dscr = NULL;
if (format_flags & FORMAT_VAT) {
/* update lvint to reflect the newest values (no writeout) */
udf_update_lvintd(UDF_INTEGRITY_CLOSED);
error = udf_append_VAT_file();
if (error)
return error;
/* write out VAT data */
sects = UDF_ROUNDUP(context.vat_size, context.sector_size) /
context.sector_size;
layout.vat = context.data_alloc_pos;
udf_data_alloc(sects, &vatdata_pos);
loc = udf_rw32(vatdata_pos.loc.lb_num);
phys = context.vtop_offset[context.data_part] + loc;
error = udf_write_phys(context.vat_contents, phys, sects);
if (error)
return error;
loc += sects;
/* create new VAT descriptor */
error = udf_create_VAT(&vat_dscr);
if (error)
return error;
context.data_alloc_pos++;
loc++;
error = udf_write_dscr_virt(vat_dscr, loc, metadata_part, 1);
free(vat_dscr);
if (error)
return error;
}
/* done */
return 0;
}

View File

@ -1,54 +0,0 @@
/* $NetBSD: udf_write.h,v 1.4 2013/08/05 20:52:08 reinoud Exp $ */
/*
* Copyright (c) 2006, 2008, 2013 Reinoud Zandijk
* 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.
*
*/
#ifndef _FS_UDF_UDF_WRITE_H_
#define _FS_UDF_UDF_WRITE_H_
#include "udf_create.h"
#if !HAVE_NBTOOL_CONFIG_H
#define _EXPOSE_MMC
#include <sys/cdio.h>
#else
#include "udf/cdio_mmc_structs.h"
#endif
/* prototypes */
int udf_write_dscr_virt(union dscrptr *dscr, uint32_t location, uint32_t vpart,
uint32_t sects);
void udf_metadata_alloc(int nblk, struct long_ad *pos);
void udf_data_alloc(int nblk, struct long_ad *pos);
int udf_derive_format(int req_enable, int req_disable, int force);
int udf_proces_names(void);
int udf_do_newfs_prefix(void);
int udf_do_rootdir(void);
int udf_do_newfs_postfix(void);
#endif /* _FS_UDF_UDF_WRITE_H_ */

View File

@ -1,161 +0,0 @@
/* $NetBSD: unicode.h,v 1.1 2013/08/05 14:11:30 reinoud Exp $ */
/*-
* Copyright (c) 2001, 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.
*
* This code is derived from software contributed to Berkeley by
* Paul Borman at Krystal Technologies.
*
* 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.
*/
/*
* Routines for handling Unicode encoded in UTF-8 form, code derived from
* src/lib/libc/locale/utf2.c.
*/
static u_int16_t wget_utf8(const char **, size_t *) __unused;
static int wput_utf8(char *, size_t, u_int16_t) __unused;
/*
* Read one UTF8-encoded character off the string, shift the string pointer
* and return the character.
*/
static u_int16_t
wget_utf8(const char **str, size_t *sz)
{
unsigned int c;
u_int16_t rune = 0;
const char *s = *str;
static const int _utf_count[16] = {
1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 2, 2, 3, 0,
};
/* must be called with at least one byte remaining */
assert(*sz > 0);
c = _utf_count[(s[0] & 0xf0) >> 4];
if (c == 0 || c > *sz) {
decoding_error:
/*
* The first character is in range 128-255 and doesn't
* mark valid a valid UTF-8 sequence. There is not much
* we can do with this, so handle by returning
* the first character as if it would be a correctly
* encoded ISO-8859-1 character.
*/
c = 1;
}
switch (c) {
case 1:
rune = s[0] & 0xff;
break;
case 2:
if ((s[1] & 0xc0) != 0x80)
goto decoding_error;
rune = ((s[0] & 0x1F) << 6) | (s[1] & 0x3F);
break;
case 3:
if ((s[1] & 0xC0) != 0x80 || (s[2] & 0xC0) != 0x80)
goto decoding_error;
rune = ((s[0] & 0x0F) << 12) | ((s[1] & 0x3F) << 6)
| (s[2] & 0x3F);
break;
}
*str += c;
*sz -= c;
return rune;
}
/*
* Encode wide character and write it to the string. 'n' specifies
* how much buffer space remains in 's'. Returns number of bytes written
* to the target string 's'.
*/
static int
wput_utf8(char *s, size_t n, u_int16_t wc)
{
if (wc & 0xf800) {
if (n < 3) {
/* bound check failure */
return 0;
}
s[0] = 0xE0 | (wc >> 12);
s[1] = 0x80 | ((wc >> 6) & 0x3F);
s[2] = 0x80 | ((wc) & 0x3F);
return 3;
} else if (wc & 0x0780) {
if (n < 2) {
/* bound check failure */
return 0;
}
s[0] = 0xC0 | (wc >> 6);
s[1] = 0x80 | ((wc) & 0x3F);
return 2;
} else {
if (n < 1) {
/* bound check failure */
return 0;
}
s[0] = wc;
return 1;
}
}

View File

@ -1,21 +0,0 @@
# $NetBSD: Makefile,v 1.4 2012/09/05 23:01:42 riz Exp $
.include <bsd.own.mk>
V7FS = ${NETBSDSRCDIR}/sys/fs/v7fs
PROG= newfs_v7fs
MAN= newfs_v7fs.8
SRCS= newfs_v7fs.c main.c v7fs_endian.c v7fs_superblock.c v7fs_inode.c \
v7fs_datablock.c v7fs_dirent.c v7fs_io.c v7fs_io_user.c progress.c
# use progress meter.
FSCK= ${NETBSDSRCDIR}/sbin/fsck
DPADD+= ${LIBUTIL}
LDADD+= -lutil
CPPFLAGS+=-DV7FS_EI -I${V7FS} -I${FSCK}
.PATH: ${V7FS} ${FSCK}
COPTS.newfs_v7fs.c+= -Wno-pointer-sign
.include <bsd.prog.mk>

View File

@ -1,316 +0,0 @@
/* $NetBSD: main.c,v 1.10 2011/08/10 11:31:49 uch Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by UCHIYAMA Yasushi.
*
* 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.
*/
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: main.c,v 1.10 2011/08/10 11:31:49 uch Exp $");
#endif /* not lint */
#include <sys/param.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <err.h>
#include "v7fs.h"
#include "v7fs_impl.h"
#include "v7fs_endian.h"
#include "v7fs_superblock.h"
#include "v7fs_inode.h"
#include "v7fs_datablock.h" /*v7fs_datablock_expand/last */
#include "newfs_v7fs.h"
#include "progress.h" /*../sbin/fsck */
#define VPRINTF(lv, fmt, args...) { if (v7fs_newfs_verbose >= lv) \
printf(fmt, ##args); }
static v7fs_daddr_t
determine_ilist_size(v7fs_daddr_t volume_size, int32_t files)
{
v7fs_daddr_t ilist_size;
if (files)
ilist_size = howmany(files, V7FS_INODE_PER_BLOCK);
else
ilist_size = volume_size / 25; /* 4% */
if (ilist_size > (v7fs_daddr_t)V7FS_ILISTBLK_MAX)
ilist_size = V7FS_ILISTBLK_MAX;
return ilist_size;
}
static int
partition_check(struct v7fs_self *fs)
{
struct v7fs_superblock *sb = &fs->superblock;
int error;
if ((error = v7fs_superblock_load(fs))) {
if (error != EINVAL) {
/* Invalid superblock information is OK. */
warnx("Can't read superblock sector.");
}
}
sb->modified = 1;
if ((error = v7fs_superblock_writeback(fs))) {
if (errno == EROFS) {
warnx("Overwriting disk label? ");
}
warnx("Can't write superblock sector.");
}
return error;
}
static int
make_root(struct v7fs_self *fs)
{
struct v7fs_inode inode;
struct v7fs_dirent *dir;
int error;
/* INO 1 badblk (don't used) */
memset(&inode, 0, sizeof(inode));
inode.inode_number = 1;
inode.mode = V7FS_IFREG; /* V7 manner */
v7fs_inode_writeback(fs, &inode);
/* INO 2 root */
v7fs_ino_t ino;
if ((error = v7fs_inode_allocate(fs, &ino))) {
errno = error;
warn("Can't allocate / inode");
return error;
}
memset(&inode, 0, sizeof(inode));
inode.inode_number = ino;
inode.mode = 0777 | V7FS_IFDIR;
inode.uid = 0;
inode.gid = 0;
inode.nlink = 2; /* . + .. */
inode.atime = inode.mtime = inode.ctime = time(0);
/* root dirent. */
v7fs_datablock_expand(fs, &inode, sizeof(*dir) * 2);
v7fs_daddr_t blk = inode.addr[0];
void *buf;
if (!(buf = scratch_read(fs, blk))) {
v7fs_inode_deallocate(fs, ino);
errno = error = EIO;
warn("Can't read / dirent.");
return error;
}
dir = (struct v7fs_dirent *)buf; /*disk endian */
strcpy(dir[0].name, ".");
dir[0].inode_number = V7FS_VAL16(fs, ino);
strcpy(dir[1].name, "..");
dir[1].inode_number = V7FS_VAL16(fs, ino);
if (!fs->io.write(fs->io.cookie, buf, blk)) {/*writeback */
scratch_free(fs, buf);
errno = error = EIO;
warn("Can't write / dirent.");
return error;
}
scratch_free(fs, buf);
v7fs_inode_writeback(fs, &inode);
if ((error = v7fs_superblock_writeback(fs))) {
errno = error;
warnx("Can't write superblock.");
}
return error;
}
static v7fs_daddr_t
make_freeblocklist(struct v7fs_self *fs, v7fs_daddr_t listblk, uint8_t *buf)
{
uint32_t (*val32)(uint32_t) = fs->val.conv32;
uint16_t (*val16)(uint16_t) = fs->val.conv16;
struct v7fs_freeblock *fb = (struct v7fs_freeblock *)buf;
int i, j, k;
memset(buf, 0, V7FS_BSIZE);
for (i = V7FS_MAX_FREEBLOCK - 1, j = listblk + 1, k = 0; i >= 0;
i--, j++, k++) {
progress(0);
if (j == (int32_t)fs->superblock.volume_size)
{
VPRINTF(4, "\nlast freeblock #%d\n",
(*val32)(fb->freeblock[i + 1]));
memmove(fb->freeblock + 1, fb->freeblock + i + 1, k *
sizeof(v7fs_daddr_t));
fb->freeblock[0] = 0; /* Terminate link; */
fb->nfreeblock = (*val16)(k + 1);
VPRINTF(4, "last freeblock contains #%d\n",
(*val16)(fb->nfreeblock));
fs->io.write(fs->io.cookie, buf, listblk);
return 0;
}
fb->freeblock[i] = (*val32)(j);
}
fb->nfreeblock = (*val16)(k);
if (!fs->io.write(fs->io.cookie, buf, listblk)) {
errno = EIO;
warn("blk=%ld", (long)listblk);
return 0;
}
/* Return next link block */
return (*val32)(fb->freeblock[0]);
}
static int
make_filesystem(struct v7fs_self *fs, v7fs_daddr_t volume_size,
v7fs_daddr_t ilist_size)
{
struct v7fs_superblock *sb;
v7fs_daddr_t blk;
uint8_t buf[V7FS_BSIZE];
int error = 0;
int32_t i, j;
/* Setup ilist. (ilist must be zero filled. becuase of they are free) */
VPRINTF(4, "Zero clear ilist.\n");
progress(&(struct progress_arg){ .label = "zero ilist", .tick =
ilist_size / PROGRESS_BAR_GRANULE });
memset(buf, 0, sizeof buf);
for (i = V7FS_ILIST_SECTOR; i < (int32_t)ilist_size; i++) {
fs->io.write(fs->io.cookie, buf, i);
progress(0);
}
#ifndef HAVE_NBTOOL_CONFIG_H
progress_done();
#endif
VPRINTF(4, "\n");
/* Construct superblock */
sb = &fs->superblock;
sb->volume_size = volume_size;
sb->datablock_start_sector = ilist_size + V7FS_ILIST_SECTOR;
sb->update_time = time(NULL);
/* fill free inode cache. */
VPRINTF(4, "Setup inode cache.\n");
sb->nfreeinode = V7FS_MAX_FREEINODE;
for (i = V7FS_MAX_FREEINODE - 1, j = V7FS_ROOT_INODE; i >= 0; i--, j++)
sb->freeinode[i] = j;
sb->total_freeinode = ilist_size * V7FS_INODE_PER_BLOCK - 1;
/* fill free block cache. */
VPRINTF(4, "Setup free block cache.\n");
sb->nfreeblock = V7FS_MAX_FREEBLOCK;
for (i = V7FS_MAX_FREEBLOCK - 1, j = sb->datablock_start_sector; i >= 0;
i--, j++)
sb->freeblock[i] = j;
sb->total_freeblock = volume_size - sb->datablock_start_sector;
/* Write superblock. */
sb->modified = 1;
if ((error = v7fs_superblock_writeback(fs))) {
errno = error;
warn("Can't write back superblock.");
return error;
}
/* Construct freeblock list */
VPRINTF(4, "Setup whole freeblock list.\n");
progress(&(struct progress_arg){ .label = "freeblock list", .tick =
(volume_size - sb->datablock_start_sector) / PROGRESS_BAR_GRANULE});
blk = sb->freeblock[0];
while ((blk = make_freeblocklist(fs, blk, buf)))
continue;
#ifndef HAVE_NBTOOL_CONFIG_H
progress_done();
#endif
VPRINTF(4, "done.\n");
return 0;
}
int
v7fs_newfs(const struct v7fs_mount_device *mount, int32_t maxfile)
{
struct v7fs_self *fs;
v7fs_daddr_t ilist_size;
int error;
v7fs_daddr_t volume_size = mount->sectors;
/* Check and determine ilistblock, datablock size. */
if (volume_size > V7FS_DADDR_MAX + 1) {
warnx("volume size %d over v7fs limit %d. truncated.",
volume_size, V7FS_DADDR_MAX + 1);
volume_size = V7FS_DADDR_MAX + 1;
}
ilist_size = determine_ilist_size(volume_size, maxfile);
VPRINTF(1, "volume size=%d, ilist size=%d, endian=%d, NAME_MAX=%d\n",
volume_size, ilist_size, mount->endian, V7FS_NAME_MAX);
/* Setup I/O ops. */
if ((error = v7fs_io_init(&fs, mount, V7FS_BSIZE))) {
errno = error;
warn("I/O setup failed.");
return error;
}
fs->endian = mount->endian;
v7fs_endian_init(fs);
if ((error = partition_check(fs))) {
return error;
}
/* Construct filesystem. */
if ((error = make_filesystem(fs, volume_size, ilist_size))) {
return error;
}
/* Setup root. */
if ((error = make_root(fs))) {
return error;
}
v7fs_io_fini(fs);
return 0;
}

View File

@ -1,139 +0,0 @@
.\" $NetBSD: newfs_v7fs.8,v 1.4 2016/09/12 05:16:04 sevan Exp $
.\"
.\" Copyright (c) 2011 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
.\" by UCHIYAMA Yasushi.
.\"
.\" 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.
.\"
.\" @(#)newlfs.8 8.1 (Berkeley) 6/19/93
.\"
.Dd September 12, 2016
.Dt NEWFS_V7FS 8
.Os
.Sh NAME
.Nm newfs_v7fs
.Nd construct a new 7th Edition(V7) File System
.Sh SYNOPSIS
.Nm
.Op Fl FZ
.Op Fl B Ar byte-order
.Op Fl n Ar inodes
.Op Fl s Ar sectors
.Op Fl V Ar verbose
.Ar special
.Sh DESCRIPTION
.Nm
builds a 7th Edition(V7) file system on the specified
.Ar special .
If it is a device, the size information will be taken from the disk label and
before running
.Nm
the disk must be labeled using
.Xr disklabel 8 ;
the proper fstype is
.Dq Version 7 .
Otherwise, the size must be specified on the command line.
V7 filesystem's block size and sector size are 512 byte.
Disk address limits are 24 bit.
.Pp
The following arguments are supported:
.Bl -tag -width XBXbyteXorderXX
.It Fl B Ar byte-order
Specify the metadata byte order of the file system to be created.
Valid byte orders are
.Sq be ,
.Sq le ,
and
.Sq pdp .
If no byte order is specified, the file system is created in host
byte order.
.It Fl F
Create file system to a regular file (needs the
.Fl s
option).
.It Fl n Ar inodes
This specifies the number of inodes for the filesystem.
If the number of inodes exceeds 65536, it is reduced to 65536.
.It Fl s Ar sectors
Create file system with specified number of disk sectors.
.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, ilist size, endian and filename length.
.It 2
A progress bar.
.It 3
.It 4
More verbose message.
.El
The default is 3.
.It Fl Z
Fill file with zeroes instead of creating a sparse file.
.El
.Sh SEE ALSO
.Xr disklabel 5 ,
.Xr disktab 5 ,
.\" .Xr fs 5 ,
.Xr disklabel 8 ,
.Xr diskpart 8
.Sh HISTORY
A
.Nm
utility appeared in
.Nx 6.0 .
.Sh AUTHORS
.Nm
was written by
.An UCHIYAMA Yasushi Aq Mt uch@NetBSD.org .

View File

@ -1,242 +0,0 @@
/* $NetBSD: newfs_v7fs.c,v 1.5 2017/01/10 20:53:09 christos Exp $ */
/*-
* Copyright (c) 2004, 2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by UCHIYAMA Yasushi.
*
* 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: newfs_v7fs.c,v 1.5 2017/01/10 20:53:09 christos Exp $");
#endif /* not lint */
#include <sys/types.h>
#include <sys/param.h>
#include <sys/disklabel.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <err.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <fs/v7fs/v7fs.h>
#include "v7fs_impl.h"
#include "progress.h"
#include "newfs_v7fs.h"
static void usage(void) __dead;
static bool progress_bar_enable = false;
int v7fs_newfs_verbose = 3; /* newfs compatible */
int
main(int argc, char **argv)
{
const char *device;
struct disklabel d;
struct partition *p;
struct stat st;
uint32_t partsize;
int Fflag, Zflag;
int part;
int fd, ch;
int endian = _BYTE_ORDER;
int32_t maxfile = 0;
if (argc < 2)
usage();
Fflag = Zflag = partsize = 0;
while ((ch = getopt(argc, argv, "Fs:Zs:n:B:V:")) != -1) {
switch (ch) {
case 'V':
v7fs_newfs_verbose = atoi(optarg);
break;
case 'F':
Fflag = 1;
break;
case 's':
partsize = atoi(optarg);
break;
case 'n':
maxfile = atoi(optarg);
break;
case 'Z':
Zflag = 1;
break;
case 'B':
switch (optarg[0]) {
case 'l':
endian = _LITTLE_ENDIAN;
break;
case 'b':
endian = _BIG_ENDIAN;
break;
case 'p':
endian = _PDP_ENDIAN;
break;
}
break;
default:
usage();
/*NOTREACHED*/
}
}
argc -= optind;
argv += optind;
if (argc != 1)
usage();
device = argv[0];
progress_bar_enable = v7fs_newfs_verbose > 1;
if (progress_bar_enable) {
progress_switch(progress_bar_enable);
progress_init();
progress(&(struct progress_arg){ .cdev = device });
}
if (!Fflag) {
if ((fd = open(device, O_RDWR)) == -1) {
err(EXIT_FAILURE, "%s", device);
}
if (fstat(fd, &st) != 0) {
goto err_exit;
}
if (!S_ISCHR(st.st_mode)) {
warnx("not a raw device");
}
part = DISKPART(st.st_rdev);
if (ioctl(fd, DIOCGDINFO, &d) == -1) {
goto err_exit;
}
p = &d.d_partitions[part];
if (v7fs_newfs_verbose) {
printf("partition=%d size=%d offset=%d fstype=%d"
" secsize=%d\n", part, p->p_size, p->p_offset,
p->p_fstype, d.d_secsize);
}
if (p->p_fstype != FS_V7) {
warnx("not a Version 7 partition");
goto err_exit;
}
partsize = p->p_size;
} else {
off_t filesize;
uint8_t zbuf[8192] = {0, };
if (partsize == 0) {
errx(EXIT_FAILURE, "-F requires -s");
}
filesize = partsize << V7FS_BSHIFT;
fd = open(device, O_RDWR|O_CREAT|O_TRUNC, 0666);
if (fd == -1) {
err(EXIT_FAILURE, "%s", device);
}
if (Zflag) {
while (filesize > 0) {
size_t writenow = MIN(filesize,
(off_t)sizeof(zbuf));
if ((size_t)write(fd, zbuf, writenow) !=
writenow) {
err(EXIT_FAILURE, NULL);
}
filesize -= writenow;
}
} else {
if (lseek(fd, filesize - 1, SEEK_SET) == -1) {
goto err_exit;
}
if (write(fd, zbuf, 1) != 1) {
goto err_exit;
}
if (lseek(fd, 0, SEEK_SET) == -1) {
goto err_exit;
}
}
}
if (v7fs_newfs(&(struct v7fs_mount_device)
{ .device.fd = fd, .endian = endian, .sectors = partsize },
maxfile) != 0)
goto err_exit;
close(fd);
return EXIT_SUCCESS;
err_exit:
close(fd);
err(EXIT_FAILURE, NULL);
}
void
progress(const struct progress_arg *p)
{
static struct progress_arg Progress;
static char cdev[32];
static char label[32];
if (!progress_bar_enable)
return;
if (p) {
Progress = *p;
if (p->cdev)
strcpy(cdev, p->cdev);
if (p->label)
strcpy(label, p->label);
}
if (!Progress.tick)
return;
if (++Progress.cnt > Progress.tick) {
Progress.cnt = 0;
Progress.total++;
progress_bar(cdev, label, Progress.total, PROGRESS_BAR_GRANULE);
}
}
static void
usage(void)
{
(void)fprintf(stderr, "usage: \n%s [-FZ] [-B byte-order]"
" [-n inodes] [-s sectors] [-V verbose] special\n", getprogname());
exit(EXIT_FAILURE);
}

View File

@ -1,48 +0,0 @@
/* $NetBSD: newfs_v7fs.h,v 1.2 2011/08/10 11:31:49 uch Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by UCHIYAMA Yasushi.
*
* 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 _SBIN_NEWFS_V7FS_NEWFS_V7FS_H_
#define _SBIN_NEWFS_V7FS_NEWFS_V7FS_H_
#define PROGRESS_BAR_GRANULE 100
struct progress_arg {
const char *cdev;
const char *label;
off_t tick;
off_t cnt;
off_t total;
};
__BEGIN_DECLS
void progress(const struct progress_arg *);
int v7fs_newfs(const struct v7fs_mount_device *, int32_t);
extern int v7fs_newfs_verbose;
__END_DECLS
#endif /* !_SBIN_NEWFS_V7FS_NEWFS_V7FS_H_ */

View File

@ -1,14 +0,0 @@
# $NetBSD: Makefile,v 1.18 2002/08/02 15:05:57 wiz Exp $
# @(#)Makefile 8.1 (Berkeley) 6/5/93
PROG= reboot
DPADD= ${LIBUTIL}
LDADD= -lutil
CPPFLAGS+= -DSUPPORT_UTMP -DSUPPORT_UTMPX
MAN= reboot.8
MLINKS= reboot.8 halt.8 \
reboot.8 poweroff.8
LINKS= ${BINDIR}/reboot ${BINDIR}/halt \
${BINDIR}/reboot ${BINDIR}/poweroff
.include <bsd.prog.mk>

View File

@ -1,168 +0,0 @@
.\" $NetBSD: reboot.8,v 1.29 2011/02/16 19:32:26 wiz Exp $
.\"
.\" Copyright (c) 1990, 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.
.\"
.\" @(#)reboot.8 8.1 (Berkeley) 6/9/93
.\"
.Dd February 16, 2011
.Dt REBOOT 8
.Os
.Sh NAME
.Nm reboot ,
.Nm poweroff ,
.Nm halt
.Nd restarting, powering down and stopping the system
.Sh SYNOPSIS
.Nm halt
.Op Fl dlnpqvxz
.Nm poweroff
.Op Fl dlnqvxz
.Nm
.Op Fl dlnqvxz
.Op Ar arg ...
.Sh DESCRIPTION
The
.Nm poweroff ,
.Nm halt
and
.Nm
utilities flush the file system cache to disk, send all running processes
a
.Dv SIGTERM ,
wait for up to 30 seconds for them to die, send a
.Dv SIGKILL
to the survivors and, respectively, power down, halt or restart the system.
The action is logged, including entering a shutdown record into the login
accounting file and sending a message via
.Xr syslog 3 .
.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl d
Create a dump before halting or restarting.
This option is useful for debugging system dump procedures or
capturing the state of a corrupted or misbehaving system.
.It Fl l
Suppress sending a message via
.Xr syslog 3
before halting or restarting.
.It Fl n
Do not flush the file system cache.
This option should be used with extreme caution.
It can be used if a disk or a processor is on fire.
.It Fl p
Attempt to powerdown the system.
If the powerdown fails, or the system does not support
software powerdown, the system will halt.
This option is only valid for
.Nm halt .
.It Fl v
To enable verbose messages on the console, pass the
.Xr boothowto 9
flag
.Dv AB_VERBOSE
to
.Xr reboot 2 .
.It Fl x
To enable debugging messages on the console, pass the
.Xr boothowto 9
flag
.Dv AB_DEBUG
to
.Xr reboot 2 .
.It Fl z
To silence some shutdown messages on the console, pass the
.Xr boothowto 9
flag
.Dv AB_SILENT
to
.Xr reboot 2 .
.It Fl q
Do not give processes a chance to shut down before halting or restarting.
This option should not normally be used.
.El
.Pp
If there are any arguments passed to
.Nm reboot
they are concatenated with spaces and passed as
.Fa bootstr
to the
.Xr reboot 2
system call.
The string is passed to the firmware on platforms that support it.
.Pp
Normally, the
.Xr shutdown 8
utility is used when the system needs to be halted or restarted, giving
users advance warning of their impending doom.
.Sh SEE ALSO
.Xr reboot 2 ,
.Xr syslog 3 ,
.Xr utmp 5 ,
.Xr boot 8 ,
.Xr init 8 ,
.Xr rescue 8 ,
.Xr shutdown 8 ,
.Xr sync 8
.Sh HISTORY
A
.Nm
command appeared in
.At v6 .
.Pp
The
.Nm poweroff
command first appeared in
.Nx 1.5 .
.Sh CAVEATS
Once the command has begun its work, stopping it before it completes
will probably result in a system so crippled it must be
physically reset.
To prevent premature termination, the command
blocks many signals early in its execution.
However, nothing can defend against deliberate attempts to evade this.
.Pp
This command will stop the system without running any
.Xr shutdown 8
scripts.
Amongst other things, this means that swapping will not be
disabled so that
.Xr raid 4
can shutdown cleanly.
You should normally use
.Xr shutdown 8
unless you are running in single user mode.
.Sh BUGS
The single user shell will ignore the
.Dv SIGTERM
signal.
To avoid waiting for the timeout when
rebooting or halting from the single user shell, you have to
.Ic exec reboot
or
.Ic exec halt .

View File

@ -1,263 +0,0 @@
/* $NetBSD: reboot.c,v 1.40 2012/11/04 22:28:16 christos Exp $ */
/*
* Copyright (c) 1980, 1986, 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) 1980, 1986, 1993\
The Regents of the University of California. All rights reserved.");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)reboot.c 8.1 (Berkeley) 6/5/93";
#else
__RCSID("$NetBSD: reboot.c,v 1.40 2012/11/04 22:28:16 christos Exp $");
#endif
#endif /* not lint */
#include <sys/reboot.h>
#include <err.h>
#include <errno.h>
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include <util.h>
#ifdef SUPPORT_UTMPX
#include <utmpx.h>
#endif
__dead static void usage(void);
static int dohalt;
static int dopoweroff;
int
main(int argc, char *argv[])
{
const char *progname;
#if !defined(__minix)
int i;
#endif /* !defined(__minix) */
struct passwd *pw;
int ch, howto, lflag, nflag, qflag, sverrno, len;
const char *user;
char *bootstr, **av;
progname = getprogname();
if (progname[0] == '-')
progname++;
if (strcmp(progname, "halt") == 0) {
dohalt = 1;
howto = RB_HALT;
} else if (strcmp(progname, "poweroff") == 0) {
dopoweroff = 1;
howto = RB_HALT | RB_POWERDOWN;
} else
howto = 0;
lflag = nflag = qflag = 0;
while ((ch = getopt(argc, argv, "dlnpqvxz")) != -1)
switch(ch) {
case 'd':
howto |= RB_DUMP;
break;
case 'l':
lflag = 1;
break;
case 'n':
nflag = 1;
howto |= RB_NOSYNC;
break;
case 'p':
if (dohalt == 0)
usage();
howto |= RB_POWERDOWN;
break;
case 'q':
qflag = 1;
break;
case 'v':
howto |= AB_VERBOSE;
break;
case 'x':
howto |= AB_DEBUG;
break;
case 'z':
howto |= AB_SILENT;
break;
case '?':
default:
usage();
}
argc -= optind;
argv += optind;
if (argc) {
for (av = argv, len = 0; *av; av++)
len += strlen(*av) + 1;
bootstr = malloc(len + 1);
*bootstr = '\0'; /* for first strcat */
for (av = argv; *av; av++) {
strcat(bootstr, *av);
strcat(bootstr, " ");
}
bootstr[len - 1] = '\0'; /* to kill last space */
howto |= RB_STRING;
} else
bootstr = NULL;
if (geteuid())
errx(1, "%s", strerror(EPERM));
if (qflag) {
reboot(howto, bootstr);
err(1, "reboot");
}
/* Log the reboot. */
if (!lflag) {
if ((user = getlogin()) == NULL)
user = (pw = getpwuid(getuid())) ?
pw->pw_name : "???";
if (dohalt) {
openlog("halt", LOG_CONS, LOG_AUTH);
syslog(LOG_CRIT, "halted by %s", user);
} else if (dopoweroff) {
openlog("poweroff", LOG_CONS, LOG_AUTH);
syslog(LOG_CRIT, "powered off by %s", user);
} else {
openlog("reboot", LOG_CONS, LOG_AUTH);
if (bootstr)
syslog(LOG_CRIT, "rebooted by %s: %s", user,
bootstr);
else
syslog(LOG_CRIT, "rebooted by %s", user);
}
}
#ifdef SUPPORT_UTMP
logwtmp("~", "shutdown", "");
#endif
#ifdef SUPPORT_UTMPX
logwtmpx("~", "shutdown", "", INIT_PROCESS, 0);
#endif
/*
* Do a sync early on, so disks start transfers while we're off
* killing processes. Don't worry about writes done before the
* processes die, the reboot system call syncs the disks.
*/
if (!nflag)
sync();
/*
* Ignore signals that we can get as a result of killing
* parents, group leaders, etc.
*/
(void)signal(SIGHUP, SIG_IGN);
(void)signal(SIGINT, SIG_IGN);
(void)signal(SIGQUIT, SIG_IGN);
(void)signal(SIGTERM, SIG_IGN);
(void)signal(SIGTSTP, SIG_IGN);
/*
* If we're running in a pipeline, we don't want to die
* after killing whatever we're writing to.
*/
(void)signal(SIGPIPE, SIG_IGN);
/* Just stop init -- if we fail, we'll restart it. */
if (kill(1, SIGTSTP) == -1)
err(1, "SIGTSTP init");
/* Send a SIGTERM first, a chance to save the buffers. */
if (kill(-1, SIGTERM) == -1) {
/*
* If ESRCH, everything's OK: we're the only non-system
* process! That can happen e.g. via 'exec reboot' in
* single-user mode.
*/
if (errno != ESRCH) {
warn("SIGTERM all processes");
goto restart;
}
}
/*
* After the processes receive the signal, start the rest of the
* buffers on their way. Wait 5 seconds between the SIGTERM and
* the SIGKILL to pretend to give everybody a chance.
*/
sleep(2);
if (!nflag)
sync();
sleep(3);
#if !defined(__minix)
for (i = 1;; ++i) {
if (kill(-1, SIGKILL) == -1) {
if (errno == ESRCH)
break;
warn("SIGKILL all processes");
goto restart;
}
if (i > 5) {
warnx("WARNING: some process(es) wouldn't die");
break;
}
(void)sleep(2 * i);
}
#endif /* !defined(__minix) */
reboot(howto, bootstr);
warn("reboot()");
/* FALLTHROUGH */
restart:
sverrno = errno;
errx(1, "%s%s", kill(1, SIGHUP) == -1 ? "(can't restart init): " : "",
strerror(sverrno));
/* NOTREACHED */
}
static void
usage(void)
{
const char *pflag = dohalt ? "p" : "";
(void)fprintf(stderr, "usage: %s [-dln%sqvxz] [-- <boot string>]\n",
getprogname(), pflag);
exit(1);
}

View File

@ -1,30 +0,0 @@
# $NetBSD: Makefile,v 1.29 2015/09/14 05:12:52 ozaki-r Exp $
# @(#)Makefile 8.1 (Berkeley) 6/5/93
.include <bsd.own.mk>
RUMPPRG=route
MAN= route.8
SRCS= route.c show.c keywords.c rtutil.c
.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
.if (${USE_INET6} != "no")
CPPFLAGS+=-DINET6
.endif
# The Makefile over in ../../distrib/utils/x_route
# would like keywords.[ch] to always exist here, so
# they are now checked in as sources.
#
# CPPFLAGS+=-I.
# CLEANFILES+= keywords.c keywords.h
# keywords.c keywords.h : keywords.sh
# ${HOST_SH} keywords.sh
.include <bsd.prog.mk>

View File

@ -1,40 +0,0 @@
/* $NetBSD: extern.h,v 1.15 2014/11/06 21:29:32 christos 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.
*/
struct sockaddr;
struct sockaddr_x25;
struct sockaddr_ns;
void parse_show_opts(int, char * const *, int *, int *, const char **, bool);
/* show.c */
void show(int, char * const *, int);
/* route.c */
extern int nflag, Sflag;
#define NOTDEFSTRING "0.0.0.0/xxx.xxx.xxx.xxx\0"
int keyword(const char *);
const char *ns_print(struct sockaddr_ns *);
void usage(const char *)__attribute__((__noreturn__));

View File

@ -1,65 +0,0 @@
/* $NetBSD: keywords.c,v 1.10 2013/03/01 18:25:17 joerg Exp $ */
/* WARNING! This file was generated by keywords.sh */
#include "keywords.h"
struct keytab keywords[] = {
{"add", K_ADD},
{"atalk", K_ATALK},
{"blackhole", K_BLACKHOLE},
{"change", K_CHANGE},
{"cloned", K_CLONED},
{"cloning", K_CLONING},
{"delete", K_DELETE},
{"dst", K_DST},
{"expire", K_EXPIRE},
{"flush", K_FLUSH},
{"gateway", K_GATEWAY},
{"genmask", K_GENMASK},
{"get", K_GET},
{"host", K_HOST},
{"hopcount", K_HOPCOUNT},
{"iface", K_IFACE},
{"interface", K_INTERFACE},
{"ifa", K_IFA},
{"ifp", K_IFP},
{"inet", K_INET},
{"inet6", K_INET6},
{"link", K_LINK},
{"llinfo", K_LLINFO},
{"lock", K_LOCK},
{"lockrest", K_LOCKREST},
{"mask", K_MASK},
{"monitor", K_MONITOR},
{"mtu", K_MTU},
{"net", K_NET},
{"netmask", K_NETMASK},
{"nostatic", K_NOSTATIC},
{"prefixlen", K_PREFIXLEN},
{"proto1", K_PROTO1},
{"proto2", K_PROTO2},
{"recvpipe", K_RECVPIPE},
{"reject", K_REJECT},
{"rtt", K_RTT},
{"rttvar", K_RTTVAR},
{"sa", K_SA},
{"sendpipe", K_SENDPIPE},
{"show", K_SHOW},
{"ssthresh", K_SSTHRESH},
{"static", K_STATIC},
{"x25", K_X25},
{"xns", K_XNS},
{"xresolve", K_XRESOLVE},
{"flushall", K_FLUSHALL},
{"nocloned", K_NOCLONED},
{"nocloning", K_NOCLONING},
{"noblackhole", K_NOBLACKHOLE},
{"noreject", K_NOREJECT},
{"mpls", K_MPLS},
{"tag", K_TAG},
{"proxy", K_PROXY},
{0, 0}
};

View File

@ -1,64 +0,0 @@
/* $NetBSD: keywords.h,v 1.13 2013/03/01 18:25:17 joerg Exp $ */
/* WARNING! This file was generated by keywords.sh */
extern struct keytab {
const char *kt_cp;
int kt_i;
} keywords[];
#define K_ADD 1
#define K_ATALK 2
#define K_BLACKHOLE 3
#define K_CHANGE 4
#define K_CLONED 5
#define K_CLONING 6
#define K_DELETE 7
#define K_DST 8
#define K_EXPIRE 9
#define K_FLUSH 10
#define K_GATEWAY 11
#define K_GENMASK 12
#define K_GET 13
#define K_HOST 14
#define K_HOPCOUNT 15
#define K_IFACE 16
#define K_INTERFACE 17
#define K_IFA 18
#define K_IFP 19
#define K_INET 20
#define K_INET6 21
#define K_LINK 22
#define K_LLINFO 23
#define K_LOCK 24
#define K_LOCKREST 25
#define K_MASK 26
#define K_MONITOR 27
#define K_MTU 28
#define K_NET 29
#define K_NETMASK 30
#define K_NOSTATIC 31
#define K_PREFIXLEN 32
#define K_PROTO1 33
#define K_PROTO2 34
#define K_RECVPIPE 35
#define K_REJECT 36
#define K_RTT 37
#define K_RTTVAR 38
#define K_SA 39
#define K_SENDPIPE 40
#define K_SHOW 41
#define K_SSTHRESH 42
#define K_STATIC 43
#define K_X25 44
#define K_XNS 45
#define K_XRESOLVE 46
#define K_FLUSHALL 47
#define K_NOCLONED 48
#define K_NOCLONING 49
#define K_NOBLACKHOLE 50
#define K_NOREJECT 51
#define K_MPLS 52
#define K_TAG 53
#define K_PROXY 54

View File

@ -1,128 +0,0 @@
#!/bin/sh
# $NetBSD: keywords.sh,v 1.11 2013/03/01 18:25:17 joerg Exp $
# @(#)keywords 8.2 (Berkeley) 3/19/94
#
# WARNING! If you change this file, re-run it!
# This program requires "new" awk (or GNU awk).
awk=${AWK:-awk}
cat << _EOF_ > _keywords.t1
add
atalk
blackhole
change
cloned
cloning
delete
dst
expire
flush
gateway
genmask
get
host
hopcount
iface
interface
ifa
ifp
inet
inet6
link
llinfo
lock
lockrest
mask
monitor
mtu
net
netmask
nostatic
prefixlen
proto1
proto2
recvpipe
reject
rtt
rttvar
sa
sendpipe
show
ssthresh
static
x25
xns
xresolve
flushall
nocloned
nocloning
noblackhole
noreject
mpls
tag
proxy
_EOF_
################################################################
# Setup
################################################################
# This creates a stream of:
# keyword KEYWORD
# (lower case, upper case).
tr a-z A-Z < _keywords.t1 |
paste _keywords.t1 - > _keywords.t2
################################################################
# Generate the h file
################################################################
exec > keywords.h
echo '/* $'NetBSD'$ */
/* WARNING! This file was generated by keywords.sh */
extern struct keytab {
const char *kt_cp;
int kt_i;
} keywords[];
' # defines follow
$awk '{
printf("#define\tK_%s\t%d\n", $2, NR);
}' < _keywords.t2
################################################################
# Generate the c file
################################################################
exec > keywords.c
echo '/* $'NetBSD'$ */
/* WARNING! This file was generated by keywords.sh */
#include "keywords.h"
struct keytab keywords[] = {
' # initializers follow
$awk '{
printf("\t{\"%s\", K_%s},\n", $1, $2);
}' < _keywords.t2
echo ' {0, 0}
};
' # tail
################################################################
# Cleanup
################################################################
rm -f _keywords.t1 _keywords.t2
exit 0

View File

@ -1,73 +0,0 @@
/* $NetBSD: prog_ops.h,v 1.3 2014/11/06 21:29:32 christos 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
/* XXX: Keep same order with netstat! */
struct prog_ops {
int (*op_init)(void);
int (*op_sysctl)(const int *, u_int, void *, size_t *,
const void *, size_t);
int (*op_socket)(int, int, int);
int (*op_open)(const char *, int, ...);
pid_t (*op_getpid)(void);
ssize_t (*op_read)(int, void *, size_t);
ssize_t (*op_write)(int, const void *, size_t);
int (*op_shutdown)(int, int);
};
extern const struct prog_ops prog_ops;
#define prog_init prog_ops.op_init
#define prog_socket prog_ops.op_socket
#define prog_open prog_ops.op_open
#define prog_getpid prog_ops.op_getpid
#define prog_read prog_ops.op_read
#define prog_write prog_ops.op_write
#define prog_sysctl prog_ops.op_sysctl
#define prog_shutdown prog_ops.op_shutdown
#else
#define prog_init ((int (*)(void))NULL)
#define prog_socket socket
#define prog_open open
#define prog_getpid getpid
#define prog_read read
#define prog_write write
#define prog_sysctl sysctl
#define prog_shutdown shutdown
#endif
#endif /* _PROG_OPS_H_ */

View File

@ -1,449 +0,0 @@
.\" $NetBSD: route.8,v 1.55 2015/03/23 18:33:17 roy Exp $
.\"
.\" Copyright (c) 1983, 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.
.\"
.\" @(#)route.8 8.4 (Berkeley) 6/1/94
.\"
.Dd March 19, 2015
.Dt ROUTE 8
.Os
.Sh NAME
.Nm route
.Nd manually manipulate the routing tables
.Sh SYNOPSIS
.Nm
.Op Fl dfLnqSsTtv
.Ar command
.Oo
.Op Ar modifiers
.Ar args
.Oc
.Sh DESCRIPTION
.Nm
is a utility used to manually manipulate the network
routing tables.
Except for setting up the default route, it is normally not needed,
as a system routing table management daemon such as
.Xr routed 8 ,
should tend to this task.
.Pp
.Nm
can be used to modify nearly any aspect of the routing policy,
except packet forwarding, which can be manipulated through the
.Xr sysctl 8
command.
.Pp
The
.Nm
utility supports a limited number of general options,
but a rich command language, enabling the user to specify
any arbitrary request that could be delivered via the
programmatic interface discussed in
.Xr route 4 .
.Pp
.Bl -tag -width Ds
.It Fl d
Turn on debugging
.It Fl f
Remove all routes (as per
.Cm flush ) .
If used in conjunction with the
.Cm add ,
.Cm change ,
.Cm delete
or
.Cm get
commands,
.Nm
removes the routes before performing the command.
.It Fl L
Don't show link layer entries in routing table.
.It Fl n
Bypasses attempts to print host and network names symbolically
when reporting actions.
(The process of translating between symbolic
names and numerical equivalents can be quite time consuming, and
may require correct operation of the network; thus it may be expedient
to forgo this, especially when attempting to repair networking operations).
.It Fl q
Suppress all output from commands that manipulate the routing table.
.It Fl S
Print a space when a flag is missing so that flags are vertically aligned
instead of printing the flags that are set as a contiguous string.
.It Fl s
(short) Suppresses all output from a
.Cm get
command except for the actual gateway that will be used.
How the gateway is printed depends on the type of route being looked up.
.It Fl T
Show tags in the route display.
.It Fl t
Test only, don't perform any actions.
.It Fl v
(verbose) Print additional details.
.El
.Pp
The
.Nm
utility provides several commands:
.Pp
.Bl -tag -width Fl -compact
.It Cm add
Add a route.
.It Cm flush
Remove all routes.
.It Cm flushall
Remove all routes including the default gateway.
.It Cm delete
Delete a specific route.
.It Cm change
Change aspects of a route (such as its gateway).
.It Cm get
Lookup and display the route for a destination.
.It Cm show
Print out the route table similar to "netstat \-r" (see
.Xr netstat 1 ) .
.It Cm monitor
Continuously report any changes to the routing information base,
routing lookup misses, or suspected network partitionings.
.El
.Pp
The monitor command has the syntax
.Pp
.Bd -filled -offset indent -compact
.Nm
.Op Fl n
.Cm monitor
.Ed
.Pp
The flush command has the syntax
.Pp
.Bd -filled -offset indent -compact
.Nm
.Op Fl n
.Cm flush
.Op Ar family
.Ed
.Pp
If the
.Cm flush
command is specified,
.Nm
will ``flush'' the routing tables of all gateway entries.
When the address family is specified by any of the
.Fl xns ,
.Fl atalk ,
.Fl inet ,
.Fl inet6 ,
or
.Fl mpls
modifiers, only routes having destinations with addresses in the
delineated family will be manipulated.
.Pp
The other commands have the following syntax:
.Pp
.Bd -filled -offset indent -compact
.Nm
.Op Fl n
.Ar command
.Op Fl net No \&| Fl host
.Ar destination gateway
.Ed
.Pp
where
.Ar destination
is the destination host or network, and
.Ar gateway
is the next-hop intermediary via which packets should be routed.
Routes to a particular host may be distinguished from those to
a network by interpreting the Internet address specified as the
.Ar destination
argument.
The optional modifiers
.Fl net
and
.Fl host
force the destination to be interpreted as a network or a host, respectively.
Otherwise, if the
.Ar destination
has a ``local address part'' of
.Dv INADDR_ANY ,
or if the
.Ar destination
is the symbolic name of a network, then the route is
assumed to be to a network; otherwise, it is presumed to be a
route to a host.
Optionally, the
.Ar destination
can also be specified in the
.Ar net Ns / Ns Ar bits
format.
.Pp
For example,
.Li 128.32
is interpreted as
.Fl host Li 128.0.0.32 ;
.Li 128.32.130
is interpreted as
.Fl host Li 128.32.0.130 ;
.Fl net Li 128.32
is interpreted as
.Li 128.32.0.0 ;
and
.Fl net Li 128.32.130
is interpreted as
.Li 128.32.130.0 .
.Pp
The keyword
.Cm default
can be used as the
.Ar destination
to set up a default route to a smart
.Ar gateway .
If no other routes match, this default route will be used as a last resort.
.Pp
If the destination is directly reachable
via an interface requiring
no intermediary system to act as a gateway, the
.Fl interface
modifier should be specified;
the gateway given is the address of this host on the common network,
indicating the interface to be used for transmission.
.Pp
The optional modifiers
.Fl xns ,
.Fl atalk ,
and
.Fl link
specify that all subsequent addresses are in the
.Tn XNS ,
or
.Tn AppleTalk
address families,
or are specified as link-level addresses in the form described in
.Xr link_addr 3 ,
and the names must be numeric specifications rather than
symbolic names.
.Pp
The optional modifier
.Fl tag
specifies an address associated with the route.
How the address is used is specific to the address family of
the destination and the interface used to forward the packet.
Currently route tags are consumed only by the
.Xr mpls 4
stack; therefore
.Nm
assumes that the subsequent addresses are in the
.Tn MPLS
address family.
See
.Xr mpls 4
for examples of setting routes involving MPLS.
.Pp
The optional
.Fl netmask
qualifier is intended
to achieve the effect of an
.Tn ESIS
redirect with the netmask option,
or to manually add subnet routes with
netmasks different from that of the implied network interface
(as would otherwise be communicated using the OSPF or ISIS routing protocols).
One specifies an additional ensuing address parameter
(to be interpreted as a network mask).
The implicit network mask generated in the
.Dv AF_INET
case
can be overridden by making sure this option follows the destination parameter.
.Fl prefixlen
is also available for similar purpose, in IPv4 and IPv6 case.
.Pp
Routes have associated flags which influence operation of the protocols
when sending to destinations matched by the routes.
These flags are displayed using the following ID characters in the routing
display and may be set (or sometimes cleared)
by indicating the following corresponding modifiers:
.Bl -column "ID" "xnoblackhole" "xRTF_BLACKHOLE" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
.It Sy "ID" Ta Sy "Modifier" Ta Sy " Flag Bit" Ta Sy "Description"
.It Li " " Ta -iface Ta ~RTF_GATEWAY Ta destination is directly reachable
.It Li 1 Ta -proto1 Ta " RTF_PROTO1" Ta set protocol specific flag #1
.It Li 2 Ta -proto2 Ta " RTF_PROTO2" Ta set protocol specific flag #2
.It Li B Ta -blackhole Ta " RTF_BLACKHOLE" Ta discard pkts (during updates)
.It Li b Ta "" Ta " RTF_BROADCAST" Ta Route represents a broadcast address
.It Li " " Ta -noblackhole Ta ~RTF_BLACKHOLE Ta clear blackhole flag
.It Li C Ta -cloning Ta " RTF_CLONING" Ta generates a new route on use
.It Li " " Ta -nocloning Ta ~RTF_CLONING Ta stop generating new routes on use
.It Li c Ta -cloned Ta " RTF_CLONED" Ta route generated by RTF_CLONING
.It Li " " Ta -nocloned Ta ~RTF_CLONED Ta deny removal with RTF_CLONING
.It Li D Ta "" Ta " RTF_DYNAMIC" Ta created dynamically (redirect)
.It Li G Ta "" Ta " RTF_GATEWAY" Ta forwarded to dest by intermediary
.It Li H Ta "" Ta " RTF_HOST" Ta host entry (net otherwise)
.It Li L Ta -llinfo Ta " RTF_LLINFO" Ta translate proto to link addr
.It Li l Ta "" Ta " RTF_LOCAL" Ta Route represents a local address
.It Li M Ta "" Ta " RTF_MODIFIED" Ta modified dynamically (redirect)
.It Li p Ta -proxy Ta " RTF_ANNOUNCE" Ta make entry a link level proxy
.It Li R Ta -reject Ta " RTF_REJECT" Ta send ICMP unreachable on match
.It Li " " Ta -noreject Ta ~RTF_REJECT Ta clear reject flag
.It Li S Ta -static Ta " RTF_STATIC" Ta manually added route
.It Li " " Ta -nostatic Ta ~RTF_STATIC Ta pretend route added automatically
.It Li U Ta "" Ta " RTF_UP" Ta route usable
.It Li X Ta -xresolve Ta " RTF_XRESOLVE" Ta emit mesg on use (for ext lookup)
.El
.Pp
The optional modifiers
.Fl rtt ,
.Fl rttvar ,
.Fl sendpipe ,
.Fl recvpipe ,
.Fl mtu ,
.Fl hopcount ,
.Fl expire ,
and
.Fl ssthresh
provide initial values to quantities maintained in the routing entry
by transport level protocols, such as TCP or TP4.
These may be individually locked by preceding each such modifier to
be locked by
the
.Fl lock
meta-modifier, or one can
specify that all ensuing metrics may be locked by the
.Fl lockrest
meta-modifier.
.Pp
In a
.Cm change
or
.Cm add
command where the destination and gateway are not sufficient to specify
the route the
.Fl ifp
or
.Fl ifa
modifiers may be used to determine the interface or interface address.
.Pp
All symbolic names specified for a
.Ar destination
or
.Ar gateway
are looked up first as a host name using
.Xr gethostbyname 3 .
If this lookup fails,
.Xr getnetbyname 3
is then used to interpret the name as that of a network.
.Pp
.Nm
uses a routing socket and the new message types
.Dv RTM_ADD ,
.Dv RTM_DELETE ,
.Dv RTM_GET ,
and
.Dv RTM_CHANGE .
As such, only the super-user may modify
the routing tables.
.Sh EXIT STATUS
The
.Nm
utility exits 0 on success, and \*[Gt]0 if an error occurs.
This includes the use of the
.Cm get
command to look up a route that is incomplete.
.Sh EXAMPLES
This sets the default route to 192.168.0.1:
.Dl route add default 192.168.0.1
This shows all routes, without DNS resolution (this is useful if the
DNS is not available):
.Dl route -n show
To install a static route through 10.200.0.1 to reach the network
192.168.1.0/28, use this:
.Dl route add -net 192.168.1.0 -netmask 255.255.255.240 10.200.0.1
.Sh DIAGNOSTICS
.Bl -tag -width Ds
.It Sy "add [host \&| network ] %s: gateway %s flags %x"
The specified route is being added to the tables.
The values printed are from the routing table entry supplied in the
.Xr ioctl 2
call.
If the gateway address used was not the primary address of the gateway
(the first one returned by
.Xr gethostbyname 3 ) ,
the gateway address is printed numerically as well as symbolically.
.It Sy "delete [ host \&| network ] %s: gateway %s flags %x"
As above, but when deleting an entry.
.It Sy "%s %s done"
When the
.Cm flush
command is specified, each routing table entry deleted
is indicated with a message of this form.
.It Sy "Network is unreachable"
An attempt to add a route failed because the gateway listed was not
on a directly-connected network.
The next-hop gateway must be given.
.It Sy "not in table"
A delete operation was attempted for an entry which
wasn't present in the tables.
.It Sy "routing table overflow"
An add operation was attempted, but the system was
low on resources and was unable to allocate memory
to create the new entry.
.It Sy "Permission denied"
The attempted operation is privileged.
Only root may modify the routing tables.
These privileges are enforced by the kernel.
.El
.Sh SEE ALSO
.Xr mpls 4 ,
.Xr netintro 4 ,
.Xr route 4 ,
.Xr routed 8 ,
.Xr sysctl 8
.\" .Xr XNSrouted 8
.Sh HISTORY
The
.Nm
command appeared in
.Bx 4.2 .
IPv6 support was added by WIDE/KAME project.
.Sh BUGS
The first paragraph may have slightly exaggerated
.Xr routed 8 Ns 's
abilities.
.Pp
Some uses of the
.Fl ifa
or
.Fl ifp
modifiers with the add command will incorrectly fail with a
.Dq Network is unreachable
message if there is no default route.
See case
.Dv RTM_ADD
in
.Pa sys/net/rtsock.c:route_output
for details.

File diff suppressed because it is too large Load Diff

View File

@ -1,54 +0,0 @@
/* $NetBSD: route_hostops.c,v 1.1 2010/12/13 17:39:47 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: route_hostops.c,v 1.1 2010/12/13 17:39:47 pooka Exp $");
#endif /* !lint */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <fcntl.h>
#include <unistd.h>
#include "prog_ops.h"
const struct prog_ops prog_ops = {
.op_socket = socket,
.op_open = open,
.op_getpid = getpid,
.op_read = read,
.op_write = write,
.op_sysctl = sysctl,
.op_shutdown = shutdown,
};

View File

@ -1,58 +0,0 @@
/* $NetBSD: route_rumpops.c,v 1.1 2010/12/13 17:39:47 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: route_rumpops.c,v 1.1 2010/12/13 17:39:47 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_open = rump_sys_open,
.op_getpid = rump_sys_getpid,
.op_read = rump_sys_read,
.op_write = rump_sys_write,
.op_sysctl = rump_sys___sysctl,
.op_shutdown = rump_sys_shutdown,
};

View File

@ -1,806 +0,0 @@
/* $NetBSD: rtutil.c,v 1.6 2015/03/23 18:33:17 roy Exp $ */
/* $OpenBSD: show.c,v 1.1 2006/05/27 19:16:37 claudio Exp $ */
/*
* Copyright (c) 1983, 1988, 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/param.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/mbuf.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_types.h>
#include <net/pfvar.h>
#include <net/pfkeyv2.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netatalk/at.h>
#include <netmpls/mpls.h>
#include <arpa/inet.h>
#include <err.h>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "prog_ops.h"
#include "rtutil.h"
#define PLEN (LONG_BIT / 4 + 2)
#define PFKEYV2_CHUNK sizeof(u_int64_t)
static char *link_print(const struct sockaddr *);
/*
* Definitions for showing gateway flags.
*/
struct bits {
int b_mask;
char b_val;
};
static const struct bits bits[] = {
{ RTF_UP, 'U' },
{ RTF_GATEWAY, 'G' },
{ RTF_HOST, 'H' },
{ RTF_REJECT, 'R' },
{ RTF_BLACKHOLE, 'B' },
{ RTF_DYNAMIC, 'D' },
{ RTF_MODIFIED, 'M' },
{ RTF_DONE, 'd' }, /* Completed -- for routing messages only */
{ RTF_MASK, 'm' }, /* Mask Present -- for routing messages only */
{ RTF_CLONING, 'C' },
{ RTF_XRESOLVE, 'X' },
{ RTF_LLINFO, 'L' },
{ RTF_STATIC, 'S' },
{ RTF_PROTO1, '1' },
{ RTF_PROTO2, '2' },
/* { RTF_PROTO3, '3' }, */
{ RTF_CLONED, 'c' },
/* { RTF_JUMBO, 'J' }, */
{ RTF_ANNOUNCE, 'p' },
{ RTF_LOCAL, 'l'},
{ RTF_BROADCAST, 'b'},
{ 0, 0 }
};
#ifndef SMALL
static void p_tag(const struct sockaddr *sa);
#endif
static void p_rtentry(struct rt_msghdr *, int, int);
/*
* Print routing tables.
*/
void
p_rttables(int paf, int flags, int pflags, int interesting)
{
struct rt_msghdr *rtm;
char *buf = NULL, *next, *lim = NULL;
size_t needed;
int mib[6];
struct sockaddr *sa;
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0;
mib[3] = paf;
mib[4] = NET_RT_DUMP;
mib[5] = 0;
if (prog_sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
err(1, "route-sysctl-estimate");
if (needed > 0) {
if ((buf = malloc(needed)) == 0)
err(1, NULL);
if (prog_sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
err(1, "sysctl of routing table");
lim = buf + needed;
}
printf("Routing tables\n");
if (buf) {
for (next = buf; next < lim; next += rtm->rtm_msglen) {
rtm = (struct rt_msghdr *)next;
sa = (struct sockaddr *)(rtm + 1);
if ((rtm->rtm_flags & pflags) != pflags)
continue;
if (paf != AF_UNSPEC && sa->sa_family != paf)
continue;
p_rtentry(rtm, flags, interesting);
}
free(buf);
buf = NULL;
}
if (paf != 0 && paf != PF_KEY)
return;
#if 0 /* XXX-elad */
mib[0] = CTL_NET;
mib[1] = PF_KEY;
mib[2] = PF_KEY_V2;
mib[3] = NET_KEY_SPD_DUMP;
mib[4] = mib[5] = 0;
if (prog_sysctl(mib, 4, NULL, &needed, NULL, 0) == -1) {
if (errno == ENOPROTOOPT)
return;
err(1, "spd-sysctl-estimate");
}
if (needed > 0) {
if ((buf = malloc(needed)) == 0)
err(1, NULL);
if (prog_sysctl(mib, 4, buf, &needed, NULL, 0) == -1)
err(1,"sysctl of spd");
lim = buf + needed;
}
if (buf) {
printf("\nEncap:\n");
for (next = buf; next < lim; next += msg->sadb_msg_len *
PFKEYV2_CHUNK) {
msg = (struct sadb_msg *)next;
if (msg->sadb_msg_len == 0)
break;
p_pfkentry(msg);
}
free(buf);
buf = NULL;
}
#endif /* 0 */
}
/*
* column widths; each followed by one space
* width of destination/gateway column
* strlen("fe80::aaaa:bbbb:cccc:dddd@gif0") == 30, strlen("/128") == 4 = 34
* strlen("aaaa:bbbb:cccc:dddd:eeee:ffff:gggg:hhhh") == 39
*/
#ifndef INET6
#define WID_DST(af) 18 /* width of destination column */
#define WID_GW(af) 18 /* width of gateway column */
#else
#define WID_DST(af) ((af) == AF_INET6 ? ((flags & RT_NFLAG) ? 39 : 18) : 18)
#define WID_GW(af) ((af) == AF_INET6 ? ((flags & RT_NFLAG) ? 30 : 18) : 18)
#endif
/*
* Print header for routing table columns.
*/
void
p_rthdr(int paf, int flags)
{
#ifndef SMALL
if (flags & RT_AFLAG)
printf("%-*.*s ", PLEN, PLEN, "Address");
if (paf == PF_KEY) {
printf("%-18s %-5s %-18s %-5s %-5s %-22s\n",
"Source", "Port", "Destination",
"Port", "Proto", "SA(Address/Proto/Type/Direction)");
return;
}
if (flags & RT_TFLAG) {
printf("%-*.*s %-*.*s %-6.6s %6.6s %8.8s %6.6s %7.7s"
" %s\n", WID_DST(paf), WID_DST(paf), "Destination",
WID_GW(paf), WID_GW(paf), "Gateway",
"Flags", "Refs", "Use", "Mtu", "Tag", "Interface");
return;
}
#endif
#ifndef SMALL
printf("%-*.*s %-*.*s %-6.6s %6.6s %8.8s %6.6s %s\n",
WID_DST(paf), WID_DST(paf), "Destination",
WID_GW(paf), WID_GW(paf), "Gateway",
"Flags", "Refs", "Use", "Mtu", "Interface");
#else
printf("%-*.*s %-*.*s %-6.6s\n",
WID_DST(paf), WID_DST(paf), "Destination",
WID_GW(paf), WID_GW(paf), "Gateway",
"Flags");
#endif
}
static void
get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
{
int i;
for (i = 0; i < RTAX_MAX; i++) {
if (addrs & (1 << i)) {
rti_info[i] = sa;
sa = (struct sockaddr *)((char *)(sa) +
RT_ROUNDUP(sa->sa_len));
} else
rti_info[i] = NULL;
}
}
/*
* Print a routing table entry.
*/
static void
p_rtentry(struct rt_msghdr *rtm, int flags, int interesting)
{
static int old_af = -1;
struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
struct sockaddr *mask, *rti_info[RTAX_MAX];
#ifndef SMALL
char ifbuf[IF_NAMESIZE];
#endif
if ((flags & RT_LFLAG) && (rtm->rtm_flags & RTF_LLINFO))
return;
if (old_af != sa->sa_family) {
old_af = sa->sa_family;
p_family(sa->sa_family);
p_rthdr(sa->sa_family, flags);
}
get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
mask = rti_info[RTAX_NETMASK];
if ((sa = rti_info[RTAX_DST]) == NULL)
return;
p_sockaddr(sa, mask, rtm->rtm_flags, WID_DST(sa->sa_family), flags);
p_sockaddr(rti_info[RTAX_GATEWAY], NULL, RTF_HOST,
WID_GW(sa->sa_family), flags);
p_flags(rtm->rtm_flags & interesting);
#if 0 /* XXX-elad */
printf("%6d %8"PRId64" ", (int)rtm->rtm_rmx.rmx_refcnt,
rtm->rtm_rmx.rmx_pksent);
#else
printf("%6s %8s ", "-", "-");
#endif
#ifndef SMALL
if (rtm->rtm_rmx.rmx_mtu)
printf("%6"PRId64, rtm->rtm_rmx.rmx_mtu);
else
printf("%6s", "-");
putchar((rtm->rtm_rmx.rmx_locks & RTV_MTU) ? 'L' : ' ');
if (flags & RT_TFLAG)
p_tag(rti_info[RTAX_TAG]);
printf(" %.16s", if_indextoname(rtm->rtm_index, ifbuf));
putchar('\n');
if (flags & RT_VFLAG)
p_rtrmx(&rtm->rtm_rmx);
#endif
}
/*
* Print address family header before a section of the routing table.
*/
void
p_family(int paf)
{
const char *afname;
switch (paf) {
case AF_INET:
afname = "Internet";
break;
#ifdef INET6
case AF_INET6:
afname = "Internet6";
break;
#endif
case PF_KEY:
afname = "Encap";
break;
case AF_APPLETALK:
afname = "AppleTalk";
break;
#ifndef SMALL
case AF_MPLS:
afname = "MPLS";
break;
#endif
default:
afname = NULL;
break;
}
if (afname)
printf("\n%s:\n", afname);
else
printf("\nProtocol Family %d:\n", paf);
}
void
p_sockaddr(const struct sockaddr *sa, const struct sockaddr *mask, int rflags,
int width, int flags)
{
char *cp;
switch (sa->sa_family) {
#ifdef INET6
case AF_INET6:
{
struct sockaddr_in6 sa6 = *(const struct sockaddr_in6 *)sa;
inet6_getscopeid(&sa6, INET6_IS_ADDR_LINKLOCAL|
INET6_IS_ADDR_MC_LINKLOCAL);
if (rflags & RTF_HOST)
cp = routename((const struct sockaddr *)&sa6, flags);
else
cp = netname((const struct sockaddr *)&sa6, mask, flags);
break;
}
#endif
default:
if ((rflags & RTF_HOST) || mask == NULL)
cp = routename(sa, flags);
else
cp = netname(sa, mask, flags);
break;
}
if (width < 0)
printf("%s", cp);
else {
if (flags & RT_NFLAG)
printf("%-*s ", width, cp);
else
printf("%-*.*s ", width, width, cp);
}
}
void
p_flags(int f)
{
char name[33], *flags;
const struct bits *p = bits;
for (flags = name; p->b_mask && flags < &name[sizeof(name) - 2]; p++)
if (p->b_mask & f)
*flags++ = p->b_val;
*flags = '\0';
printf("%-6.6s ", name);
}
#ifndef SMALL
void
p_rtrmx(const struct rt_metrics *rmx)
{
printf("\texpire %10"PRId64"%c recvpipe %10"PRIu64"%c "
"sendpipe %10"PRIu64"%c\n",
(int64_t)rmx->rmx_expire,
(rmx->rmx_locks & RTV_EXPIRE) ? 'L' : ' ', rmx->rmx_recvpipe,
(rmx->rmx_locks & RTV_RPIPE) ? 'L' : ' ', rmx->rmx_sendpipe,
(rmx->rmx_locks & RTV_SPIPE) ? 'L' : ' ');
printf("\tssthresh %10"PRIu64"%c rtt %10"PRIu64"%c "
"rttvar %10"PRIu64"%c\n", rmx->rmx_ssthresh,
(rmx->rmx_locks & RTV_SSTHRESH) ? 'L' : ' ',
rmx->rmx_rtt, (rmx->rmx_locks & RTV_RTT) ? 'L' : ' ',
rmx->rmx_rttvar, (rmx->rmx_locks & RTV_RTTVAR) ? 'L' : ' ');
printf("\thopcount %10"PRIu64"%c\n",
rmx->rmx_hopcount, (rmx->rmx_locks & RTV_HOPCOUNT) ? 'L' : ' ');
}
static void
p_tag(const struct sockaddr *sa)
{
char *line;
if (sa == NULL || sa->sa_family != AF_MPLS) {
printf("%7s", "-");
return;
}
line = mpls_ntoa(sa);
if (strlen(line) < 7)
printf("%7s", line);
else
printf("%s", line);
}
#endif
static char line[MAXHOSTNAMELEN];
static char domain[MAXHOSTNAMELEN];
char *
routename(const struct sockaddr *sa, int flags)
{
char *cp = NULL;
static int first = 1;
if (first) {
first = 0;
if (gethostname(domain, sizeof(domain)) == 0 &&
(cp = strchr(domain, '.')))
(void)strlcpy(domain, cp + 1, sizeof(domain));
else
domain[0] = '\0';
cp = NULL;
}
if (sa->sa_len == 0) {
(void)strlcpy(line, "default", sizeof(line));
return (line);
}
switch (sa->sa_family) {
case AF_INET:
return routename4(
((const struct sockaddr_in *)sa)->sin_addr.s_addr,
flags);
#ifdef INET6
case AF_INET6:
{
struct sockaddr_in6 sin6;
memset(&sin6, 0, sizeof(sin6));
memcpy(&sin6, sa, sa->sa_len);
sin6.sin6_len = sizeof(struct sockaddr_in6);
sin6.sin6_family = AF_INET6;
if (sa->sa_len == sizeof(struct sockaddr_in6))
#if defined(__minix)
/*
* Local MINIX3 fix for a NetBSD issue: inet6_getscopeid()
* is sometimes called twice in a row when printing routing
* tables, discarding the scope ID the second time..
*/
if (sin6.sin6_scope_id == 0)
#endif /* defined(__minix) */
inet6_getscopeid(&sin6, INET6_IS_ADDR_LINKLOCAL|
INET6_IS_ADDR_MC_LINKLOCAL);
return routename6(&sin6, flags);
}
#endif
case AF_LINK:
return link_print(sa);
#ifndef SMALL
case AF_MPLS:
return mpls_ntoa(sa);
case AF_APPLETALK:
(void)snprintf(line, sizeof(line), "atalk %d.%d",
((const struct sockaddr_at *)sa)->sat_addr.s_net,
((const struct sockaddr_at *)sa)->sat_addr.s_node);
break;
#endif
#if 0 /* XXX-elad */
case AF_UNSPEC:
if (sa->sa_len == sizeof(struct sockaddr_rtlabel)) {
static char name[RTLABEL_LEN];
struct sockaddr_rtlabel *sr;
sr = (struct sockaddr_rtlabel *)sa;
strlcpy(name, sr->sr_label, sizeof(name));
return (name);
}
/* FALLTHROUGH */
#endif
default:
(void)snprintf(line, sizeof(line), "(%d) %s",
sa->sa_family, any_ntoa(sa));
break;
}
return (line);
}
char *
routename4(in_addr_t in, int flags)
{
const char *cp = NULL;
struct in_addr ina;
struct hostent *hp;
if (in == INADDR_ANY)
cp = "default";
if (!cp && (flags & RT_NFLAG) == 0) {
if ((hp = gethostbyaddr((char *)&in,
sizeof(in), AF_INET)) != NULL) {
char *p;
if ((p = strchr(hp->h_name, '.')) &&
!strcmp(p + 1, domain))
*p = '\0';
cp = hp->h_name;
}
}
ina.s_addr = in;
strlcpy(line, cp ? cp : inet_ntoa(ina), sizeof(line));
return (line);
}
#ifdef INET6
char *
routename6(const struct sockaddr_in6 *sin6, int flags)
{
int niflags = 0;
if ((flags & RT_NFLAG))
niflags |= NI_NUMERICHOST;
else
niflags |= NI_NOFQDN;
if (getnameinfo((const struct sockaddr *)sin6, sin6->sin6_len,
line, sizeof(line), NULL, 0, niflags) != 0)
strncpy(line, "invalid", sizeof(line));
return (line);
}
#endif
/*
* Return the name of the network whose address is given.
* The address is assumed to be that of a net or subnet, not a host.
*/
char *
netname4(const struct sockaddr_in* sa4, const struct sockaddr_in *mask, int flags)
{
const char *cp = NULL;
struct netent *np = NULL;
int mbits;
in_addr_t in = sa4->sin_addr.s_addr;
if (mask) {
in_addr_t m = mask->sin_addr.s_addr ;
m = ntohl(m);
mbits = m ? 33 - ffs(m) : 0;
} else
mbits = 0;
in = ntohl(in);
if (in == INADDR_ANY && !mbits)
cp = "default";
else if (!(flags & RT_NFLAG) && in != INADDR_ANY) {
if ((np = getnetbyaddr(in, AF_INET)) != NULL)
cp = np->n_name;
}
if (cp)
strlcpy(line, cp, sizeof(line));
#define C(x) ((x) & 0xff)
else if (mbits < 9)
snprintf(line, sizeof(line), "%u/%d", C(in >> 24), mbits);
else if (mbits < 17)
snprintf(line, sizeof(line), "%u.%u/%d",
C(in >> 24) , C(in >> 16), mbits);
else if (mbits < 25)
snprintf(line, sizeof(line), "%u.%u.%u/%d",
C(in >> 24), C(in >> 16), C(in >> 8), mbits);
else
snprintf(line, sizeof(line), "%u.%u.%u.%u/%d", C(in >> 24),
C(in >> 16), C(in >> 8), C(in), mbits);
#undef C
return line;
}
#ifdef INET6
char *
netname6(const struct sockaddr_in6 *sa6, const struct sockaddr_in6 *mask, int flags)
{
struct sockaddr_in6 sin6;
const u_char *p;
int masklen, final = 0, illegal = 0;
int i, lim, flag, error;
char hbuf[NI_MAXHOST];
sin6 = *sa6;
flag = 0;
masklen = 0;
if (mask) {
lim = mask->sin6_len - offsetof(struct sockaddr_in6, sin6_addr);
if (lim < 0)
lim = 0;
else if (lim > (int)sizeof(struct in6_addr))
lim = sizeof(struct in6_addr);
for (p = (const u_char *)&mask->sin6_addr, i = 0; i < lim; p++) {
if (final && *p) {
illegal++;
sin6.sin6_addr.s6_addr[i++] = 0x00;
continue;
}
switch (*p & 0xff) {
case 0xff:
masklen += 8;
break;
case 0xfe:
masklen += 7;
final++;
break;
case 0xfc:
masklen += 6;
final++;
break;
case 0xf8:
masklen += 5;
final++;
break;
case 0xf0:
masklen += 4;
final++;
break;
case 0xe0:
masklen += 3;
final++;
break;
case 0xc0:
masklen += 2;
final++;
break;
case 0x80:
masklen += 1;
final++;
break;
case 0x00:
final++;
break;
default:
final++;
illegal++;
break;
}
if (!illegal)
sin6.sin6_addr.s6_addr[i++] &= *p;
else
sin6.sin6_addr.s6_addr[i++] = 0x00;
}
while (i < (int)sizeof(struct in6_addr))
sin6.sin6_addr.s6_addr[i++] = 0x00;
} else
masklen = 128;
if (masklen == 0 && IN6_IS_ADDR_UNSPECIFIED(&sin6.sin6_addr)) {
snprintf(line, sizeof(line), "default");
return (line);
}
if (illegal)
warnx("illegal prefixlen");
if (flags & RT_NFLAG)
flag |= NI_NUMERICHOST;
error = getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
hbuf, sizeof(hbuf), NULL, 0, flag);
if (error)
snprintf(hbuf, sizeof(hbuf), "invalid");
snprintf(line, sizeof(line), "%s/%d", hbuf, masklen);
return (line);
}
#endif
/*
* Return the name of the network whose address is given.
* The address is assumed to be that of a net or subnet, not a host.
*/
char *
netname(const struct sockaddr *sa, const struct sockaddr *mask, int flags)
{
switch (sa->sa_family) {
case AF_INET:
return netname4((const struct sockaddr_in *)sa,
(const struct sockaddr_in *)mask, flags);
#ifdef INET6
case AF_INET6:
return netname6((const struct sockaddr_in6 *)sa,
(const struct sockaddr_in6 *)mask, flags);
#endif
case AF_LINK:
return link_print(sa);
default:
snprintf(line, sizeof(line), "af %d: %s",
sa->sa_family, any_ntoa(sa));
break;
}
return (line);
}
static const char hexlist[] = "0123456789abcdef";
char *
any_ntoa(const struct sockaddr *sa)
{
static char obuf[240];
const char *in = sa->sa_data;
char *out = obuf;
int len = sa->sa_len - offsetof(struct sockaddr, sa_data);
*out++ = 'Q';
do {
*out++ = hexlist[(*in >> 4) & 15];
*out++ = hexlist[(*in++) & 15];
*out++ = '.';
} while (--len > 0 && (out + 3) < &obuf[sizeof(obuf) - 1]);
out[-1] = '\0';
return (obuf);
}
static char *
link_print(const struct sockaddr *sa)
{
const struct sockaddr_dl *sdl = (const struct sockaddr_dl *)sa;
const u_char *lla = (const u_char *)sdl->sdl_data + sdl->sdl_nlen;
if (sdl->sdl_nlen == 0 && sdl->sdl_alen == 0 &&
sdl->sdl_slen == 0) {
(void)snprintf(line, sizeof(line), "link#%d", sdl->sdl_index);
return (line);
}
switch (sdl->sdl_type) {
case IFT_ETHER:
case IFT_CARP:
return ether_ntoa((const struct ether_addr *)lla);
default:
return link_ntoa(sdl);
}
}
#ifndef SMALL
char *
mpls_ntoa(const struct sockaddr *sa)
{
static char obuf[16];
size_t olen;
const union mpls_shim *pms;
union mpls_shim ms;
int psize = sizeof(struct sockaddr_mpls);
pms = &((const struct sockaddr_mpls*)sa)->smpls_addr;
ms.s_addr = ntohl(pms->s_addr);
snprintf(obuf, sizeof(obuf), "%u", ms.shim.label);
while(psize < sa->sa_len) {
pms++;
ms.s_addr = ntohl(pms->s_addr);
olen = strlen(obuf);
snprintf(obuf + olen, sizeof(obuf) - olen, ",%u",
ms.shim.label);
psize+=sizeof(ms);
}
return obuf;
}
#endif
void
p_addr(const struct sockaddr *sa, const struct sockaddr *mask, int rflags, int flags)
{
p_sockaddr(sa, mask, rflags, WID_DST(sa->sa_family), flags);
}
void
p_gwaddr(const struct sockaddr *sa, int gwaf, int flags)
{
p_sockaddr(sa, 0, RTF_HOST, WID_GW(gwaf), flags);
}

View File

@ -1,59 +0,0 @@
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas.
*
* 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 NetBSD Foundation 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 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.
*/
#define RT_AFLAG __BIT(0) /* show address field */
#define RT_TFLAG __BIT(1) /* show tag field */
#define RT_VFLAG __BIT(2) /* show verbose statistics */
#define RT_NFLAG __BIT(3) /* numeric output */
#define RT_LFLAG __BIT(4) /* don't show LLINFO entries */
void p_rttables(int, int, int, int);
void p_rthdr(int, int);
void p_family(int);
void p_sockaddr(const struct sockaddr *, const struct sockaddr *, int, int, int);
void p_flags(int);
struct rt_metrics;
void p_rtrmx(const struct rt_metrics *);
void p_addr(const struct sockaddr *sa, const struct sockaddr *mask, int, int);
void p_gwaddr(const struct sockaddr *sa, int, int);
char *routename(const struct sockaddr *sa, int);
char *routename4(in_addr_t, int);
#ifdef INET6
char *routename6(const struct sockaddr_in6 *, int);
char *netname6(const struct sockaddr_in6 *, const struct sockaddr_in6 *, int);
#endif
char *netname(const struct sockaddr *, const struct sockaddr *, int);
char *netname4(const struct sockaddr_in *, const struct sockaddr_in *, int);
char *mpls_ntoa(const struct sockaddr *);
char *any_ntoa(const struct sockaddr *);

View File

@ -1,144 +0,0 @@
/* $NetBSD: show.c,v 1.48 2015/03/23 18:33:17 roy Exp $ */
/*
* Copyright (c) 1983, 1988, 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
#if 0
static char sccsid[] = "from: @(#)route.c 8.3 (Berkeley) 3/9/94";
#else
__RCSID("$NetBSD: show.c,v 1.48 2015/03/23 18:33:17 roy Exp $");
#endif
#endif /* not lint */
#include <sys/param.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/mbuf.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netmpls/mpls.h>
#include <sys/sysctl.h>
#include <netdb.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <err.h>
#include "keywords.h"
#include "rtutil.h"
#include "extern.h"
#include "prog_ops.h"
void
parse_show_opts(int argc, char * const *argv, int *afp, int *flagsp,
const char **afnamep, bool nolink)
{
const char *afname = "unspec";
int af, flags;
flags = 0;
af = AF_UNSPEC;
for (; argc >= 2; argc--) {
if (*argv[argc - 1] != '-')
goto bad;
switch (keyword(argv[argc - 1] + 1)) {
case K_HOST:
flags |= RTF_HOST;
break;
case K_LLINFO:
flags |= RTF_LLINFO;
break;
case K_INET:
af = AF_INET;
afname = argv[argc - 1] + 1;
break;
#ifdef INET6
case K_INET6:
af = AF_INET6;
afname = argv[argc - 1] + 1;
break;
#endif
#ifndef SMALL
case K_ATALK:
af = AF_APPLETALK;
afname = argv[argc - 1] + 1;
break;
case K_MPLS:
af = AF_MPLS;
afname = argv[argc - 1] + 1;
break;
#endif /* SMALL */
case K_LINK:
if (nolink)
goto bad;
af = AF_LINK;
afname = argv[argc - 1] + 1;
break;
default:
goto bad;
}
}
switch (argc) {
case 1:
case 0:
break;
default:
bad:
usage(argv[argc - 1]);
}
if (afnamep != NULL)
*afnamep = afname;
*afp = af;
*flagsp = flags;
}
/*
* Print routing tables.
*/
void
show(int argc, char *const *argv, int flags)
{
int af, rflags;
static int interesting = RTF_UP | RTF_GATEWAY | RTF_HOST |
RTF_REJECT | RTF_LLINFO | RTF_LOCAL | RTF_BROADCAST;
parse_show_opts(argc, argv, &af, &rflags, NULL, true);
p_rttables(af, flags, rflags, interesting);
}