Merge pull request #12 from Oichkatzelesfrettschen/eirikr/delete-files-mentioning-netbsd-in-batches
This commit is contained in:
commit
0af921fe36
|
|
@ -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>
|
||||
|
|
@ -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 .
|
||||
|
|
@ -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 .
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
@ -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(¶m->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(¶m->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(¶m->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(¶m->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(¶m->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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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 .
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 *);
|
||||
|
|
@ -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 .
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
@ -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 .
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
|
|
@ -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
|
|
@ -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_ */
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 .
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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>
|
||||
|
|
@ -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 .
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
@ -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__));
|
||||
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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.
|
||||
1809
sbin/route/route.c
1809
sbin/route/route.c
File diff suppressed because it is too large
Load Diff
|
|
@ -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,
|
||||
};
|
||||
|
|
@ -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,
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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 *);
|
||||
|
|
@ -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);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user