Import Lite2's src/sbin, except for XNSrouted and routed. All relevant
files in src/sbin are off the vendor branch, so this doesn't change the active versions.
This commit is contained in:
parent
c46940197c
commit
25e43cba72
209
sbin/badsect/badsect.c
Normal file
209
sbin/badsect/badsect.c
Normal file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (c) 1981, 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. 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1981, 1983, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)badsect.c 8.2 (Berkeley) 5/4/95";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* badsect
|
||||
*
|
||||
* Badsect takes a list of file-system relative sector numbers
|
||||
* and makes files containing the blocks of which these sectors are a part.
|
||||
* It can be used to contain sectors which have problems if these sectors
|
||||
* are not part of the bad file for the pack (see bad144). For instance,
|
||||
* this program can be used if the driver for the file system in question
|
||||
* does not support bad block forwarding.
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/dir.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
union {
|
||||
struct fs fs;
|
||||
char fsx[SBSIZE];
|
||||
} ufs;
|
||||
#define sblock ufs.fs
|
||||
union {
|
||||
struct cg cg;
|
||||
char cgx[MAXBSIZE];
|
||||
} ucg;
|
||||
#define acg ucg.cg
|
||||
struct fs *fs;
|
||||
int fso, fsi;
|
||||
int errs;
|
||||
long dev_bsize = 1;
|
||||
|
||||
char buf[MAXBSIZE];
|
||||
|
||||
void rdfs __P((daddr_t, int, char *));
|
||||
int chkuse __P((daddr_t, int));
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
daddr_t number;
|
||||
struct stat stbuf, devstat;
|
||||
register struct direct *dp;
|
||||
DIR *dirp;
|
||||
char name[BUFSIZ];
|
||||
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "usage: badsect bbdir blkno [ blkno ]\n");
|
||||
exit(1);
|
||||
}
|
||||
if (chdir(argv[1]) < 0 || stat(".", &stbuf) < 0) {
|
||||
perror(argv[1]);
|
||||
exit(2);
|
||||
}
|
||||
strcpy(name, _PATH_DEV);
|
||||
if ((dirp = opendir(name)) == NULL) {
|
||||
perror(name);
|
||||
exit(3);
|
||||
}
|
||||
while ((dp = readdir(dirp)) != NULL) {
|
||||
strcpy(&name[5], dp->d_name);
|
||||
if (stat(name, &devstat) < 0) {
|
||||
perror(name);
|
||||
exit(4);
|
||||
}
|
||||
if (stbuf.st_dev == devstat.st_rdev &&
|
||||
(devstat.st_mode & IFMT) == IFBLK)
|
||||
break;
|
||||
}
|
||||
closedir(dirp);
|
||||
if (dp == NULL) {
|
||||
printf("Cannot find dev 0%o corresponding to %s\n",
|
||||
stbuf.st_rdev, argv[1]);
|
||||
exit(5);
|
||||
}
|
||||
if ((fsi = open(name, 0)) < 0) {
|
||||
perror(name);
|
||||
exit(6);
|
||||
}
|
||||
fs = &sblock;
|
||||
rdfs(SBOFF, SBSIZE, (char *)fs);
|
||||
dev_bsize = fs->fs_fsize / fsbtodb(fs, 1);
|
||||
for (argc -= 2, argv += 2; argc > 0; argc--, argv++) {
|
||||
number = atoi(*argv);
|
||||
if (chkuse(number, 1))
|
||||
continue;
|
||||
if (mknod(*argv, IFMT|0600, dbtofsb(fs, number)) < 0) {
|
||||
perror(*argv);
|
||||
errs++;
|
||||
}
|
||||
}
|
||||
printf("Don't forget to run ``fsck %s''\n", name);
|
||||
exit(errs);
|
||||
}
|
||||
|
||||
int
|
||||
chkuse(blkno, cnt)
|
||||
daddr_t blkno;
|
||||
int cnt;
|
||||
{
|
||||
int cg;
|
||||
daddr_t fsbn, bn;
|
||||
|
||||
fsbn = dbtofsb(fs, blkno);
|
||||
if ((unsigned)(fsbn+cnt) > fs->fs_size) {
|
||||
printf("block %d out of range of file system\n", blkno);
|
||||
return (1);
|
||||
}
|
||||
cg = dtog(fs, fsbn);
|
||||
if (fsbn < cgdmin(fs, cg)) {
|
||||
if (cg == 0 || (fsbn+cnt) > cgsblock(fs, cg)) {
|
||||
printf("block %d in non-data area: cannot attach\n",
|
||||
blkno);
|
||||
return (1);
|
||||
}
|
||||
} else {
|
||||
if ((fsbn+cnt) > cgbase(fs, cg+1)) {
|
||||
printf("block %d in non-data area: cannot attach\n",
|
||||
blkno);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
rdfs(fsbtodb(fs, cgtod(fs, cg)), (int)sblock.fs_cgsize,
|
||||
(char *)&acg);
|
||||
if (!cg_chkmagic(&acg)) {
|
||||
fprintf(stderr, "cg %d: bad magic number\n", cg);
|
||||
errs++;
|
||||
return (1);
|
||||
}
|
||||
bn = dtogd(fs, fsbn);
|
||||
if (isclr(cg_blksfree(&acg), bn))
|
||||
printf("Warning: sector %d is in use\n", blkno);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* read a block from the file system
|
||||
*/
|
||||
void
|
||||
rdfs(bno, size, bf)
|
||||
daddr_t bno;
|
||||
int size;
|
||||
char *bf;
|
||||
{
|
||||
int n;
|
||||
|
||||
if (lseek(fsi, (off_t)bno * dev_bsize, SEEK_SET) < 0) {
|
||||
printf("seek error: %ld\n", bno);
|
||||
perror("rdfs");
|
||||
exit(1);
|
||||
}
|
||||
n = read(fsi, bf, size);
|
||||
if (n != size) {
|
||||
printf("read error: %ld\n", bno);
|
||||
perror("rdfs");
|
||||
exit(1);
|
||||
}
|
||||
}
|
131
sbin/clri/clri.c
Normal file
131
sbin/clri/clri.c
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Rich $alz of BBN 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. 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1990, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)clri.c 8.3 (Berkeley) 4/28/95";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
register struct fs *sbp;
|
||||
register struct dinode *ip;
|
||||
register int fd;
|
||||
struct dinode ibuf[MAXBSIZE / sizeof (struct dinode)];
|
||||
long generation, bsize;
|
||||
off_t offset;
|
||||
int inonum;
|
||||
char *fs, sblock[SBSIZE];
|
||||
|
||||
if (argc < 3) {
|
||||
(void)fprintf(stderr, "usage: clri filesystem inode ...\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fs = *++argv;
|
||||
|
||||
/* get the superblock. */
|
||||
if ((fd = open(fs, O_RDWR, 0)) < 0)
|
||||
err(1, "%s", fs);
|
||||
if (lseek(fd, (off_t)(SBLOCK * DEV_BSIZE), SEEK_SET) < 0)
|
||||
err(1, "%s", fs);
|
||||
if (read(fd, sblock, sizeof(sblock)) != sizeof(sblock))
|
||||
errx(1, "%s: can't read superblock", fs);
|
||||
|
||||
sbp = (struct fs *)sblock;
|
||||
if (sbp->fs_magic != FS_MAGIC)
|
||||
errx(1, "%s: superblock magic number 0x%x, not 0x%x",
|
||||
fs, sbp->fs_magic, FS_MAGIC);
|
||||
bsize = sbp->fs_bsize;
|
||||
|
||||
/* remaining arguments are inode numbers. */
|
||||
while (*++argv) {
|
||||
/* get the inode number. */
|
||||
if ((inonum = atoi(*argv)) <= 0)
|
||||
errx(1, "%s is not a valid inode number", *argv);
|
||||
(void)printf("clearing %d\n", inonum);
|
||||
|
||||
/* read in the appropriate block. */
|
||||
offset = ino_to_fsba(sbp, inonum); /* inode to fs blk */
|
||||
offset = fsbtodb(sbp, offset); /* fs blk disk blk */
|
||||
offset *= DEV_BSIZE; /* disk blk to bytes */
|
||||
|
||||
/* seek and read the block */
|
||||
if (lseek(fd, offset, SEEK_SET) < 0)
|
||||
err(1, "%s", fs);
|
||||
if (read(fd, ibuf, bsize) != bsize)
|
||||
err(1, "%s", fs);
|
||||
|
||||
/* get the inode within the block. */
|
||||
ip = &ibuf[ino_to_fsbo(sbp, inonum)];
|
||||
|
||||
/* clear the inode, and bump the generation count. */
|
||||
generation = ip->di_gen + 1;
|
||||
memset(ip, 0, sizeof(*ip));
|
||||
ip->di_gen = generation;
|
||||
|
||||
/* backup and write the block */
|
||||
if (lseek(fd, (off_t)-bsize, SEEK_CUR) < 0)
|
||||
err(1, "%s", fs);
|
||||
if (write(fd, ibuf, bsize) != bsize)
|
||||
err(1, "%s", fs);
|
||||
(void)fsync(fd);
|
||||
}
|
||||
(void)close(fd);
|
||||
exit(0);
|
||||
}
|
388
sbin/disklabel/disklabel.5.5
Normal file
388
sbin/disklabel/disklabel.5.5
Normal file
@ -0,0 +1,388 @@
|
||||
.\" Copyright (c) 1987, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to Berkeley by
|
||||
.\" Symmetric Computer Systems.
|
||||
.\"
|
||||
.\" 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.
|
||||
.\"
|
||||
.\" @(#)disklabel.5.5 8.2 (Berkeley) 5/6/94
|
||||
.\"
|
||||
.Dd May 6, 1994
|
||||
.Dt DISKLABEL 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm disklabel
|
||||
.Nd disk pack label
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <sys/disklabel.h>
|
||||
.Sh DESCRIPTION
|
||||
Each disk or disk pack on a system may contain a disk label
|
||||
which provides detailed information
|
||||
about the geometry of the disk and the partitions into which the disk
|
||||
is divided.
|
||||
It should be initialized when the disk is formatted,
|
||||
and may be changed later with the
|
||||
.Xr disklabel 8
|
||||
program.
|
||||
This information is used by the system disk driver and by the bootstrap
|
||||
program to determine how to program the drive
|
||||
and where to find the filesystems on the disk partitions.
|
||||
Additional information is used by the filesystem in order
|
||||
to use the disk most efficiently and to locate important filesystem information.
|
||||
The description of each partition contains an identifier for the partition
|
||||
type (standard filesystem, swap area, etc.).
|
||||
The filesystem updates the in-core copy of the label if it contains
|
||||
incomplete information about the filesystem.
|
||||
.Pp
|
||||
The label is located in sector number
|
||||
.Dv LABELSECTOR
|
||||
of the drive, usually sector 0 where it may be found
|
||||
without any information about the disk geometry.
|
||||
It is at an offset
|
||||
.Dv LABELOFFSET
|
||||
from the beginning of the sector, to allow room for the initial bootstrap.
|
||||
The disk sector containing the label is normally made read-only
|
||||
so that it is not accidentally overwritten by pack-to-pack copies
|
||||
or swap operations;
|
||||
the
|
||||
.Dv DIOCWLABEL
|
||||
.Xr ioctl 2 ,
|
||||
which is done as needed by the
|
||||
.Xr disklabel
|
||||
program.
|
||||
.Pp
|
||||
A copy of the in-core label for a disk can be obtained with the
|
||||
.Dv DIOCGDINFO
|
||||
.Xr ioctl ;
|
||||
this works with a file descriptor for a block or character (``raw'') device
|
||||
for any partition of the disk.
|
||||
The in-core copy of the label is set by the
|
||||
.Dv DIOCSDINFO
|
||||
.Xr ioctl .
|
||||
The offset of a partition cannot generally be changed while it is open,
|
||||
nor can it be made smaller while it is open.
|
||||
One exception is that any change is allowed if no label was found
|
||||
on the disk, and the driver was able to construct only a skeletal label
|
||||
without partition information.
|
||||
Finally, the
|
||||
.Dv DIOCWDINFO
|
||||
.Xr ioctl
|
||||
operation sets the in-core label and then updates the on-disk label;
|
||||
there must be an existing label on the disk for this operation to succeed.
|
||||
Thus, the initial label for a disk or disk pack must be installed
|
||||
by writing to the raw disk.
|
||||
All of these operations are normally done using
|
||||
.Xr disklabel .
|
||||
.Pp
|
||||
The format of the disk label, as specified in
|
||||
.Aw Pa sys/disklabel.h ,
|
||||
is
|
||||
.Bd -literal
|
||||
/*
|
||||
* Disk description table, see disktab(5)
|
||||
*/
|
||||
#define DISKTAB "/etc/disktab"
|
||||
|
||||
/*
|
||||
* Each disk has a label which includes information about the hardware
|
||||
* disk geometry, filesystem partitions, and drive specific information.
|
||||
* The label is in block 0 or 1, possibly offset from the beginning
|
||||
* to leave room for a bootstrap, etc.
|
||||
*/
|
||||
|
||||
#ifndef LABELSECTOR
|
||||
#define LABELSECTOR 0 /* sector containing label */
|
||||
#endif
|
||||
|
||||
#ifndef LABELOFFSET
|
||||
#define LABELOFFSET 64 /* offset of label in sector */
|
||||
#endif
|
||||
|
||||
#define DISKMAGIC ((u_long) 0x82564557) /* The disk magic number */
|
||||
#ifndef MAXPARTITIONS
|
||||
#define MAXPARTITIONS 8
|
||||
#endif
|
||||
|
||||
#ifndef LOCORE
|
||||
struct disklabel {
|
||||
u_long d_magic; /* the magic number */
|
||||
short d_type; /* drive type */
|
||||
short d_subtype; /* controller/d_type specific */
|
||||
char d_typename[16]; /* type name, e.g. "eagle" */
|
||||
/*
|
||||
* d_packname contains the pack identifier and is returned when
|
||||
* the disklabel is read off the disk or in-core copy.
|
||||
* d_boot0 and d_boot1 are the (optional) names of the
|
||||
* primary (block 0) and secondary (block 1-15) bootstraps
|
||||
* as found in /usr/mdec. These are returned when using
|
||||
* getdiskbyname(3)
|
||||
to retrieve the values from /etc/disktab.
|
||||
*/
|
||||
#if defined(KERNEL) || defined(STANDALONE)
|
||||
char d_packname[16]; /* pack identifier */
|
||||
#else
|
||||
union {
|
||||
char un_d_packname[16]; /* pack identifier */
|
||||
struct {
|
||||
char *un_d_boot0; /* primary bootstrap name */
|
||||
char *un_d_boot1; /* secondary bootstrap name */
|
||||
} un_b;
|
||||
} d_un;
|
||||
|
||||
#define d_packname d_un.un_d_packname
|
||||
#define d_boot0 d_un.un_b.un_d_boot0
|
||||
#define d_boot1 d_un.un_b.un_d_boot1
|
||||
#endif /* ! KERNEL or STANDALONE */
|
||||
|
||||
/* disk geometry: */
|
||||
u_long d_secsize; /* # of bytes per sector */
|
||||
u_long d_nsectors; /* # of data sectors per track */
|
||||
u_long d_ntracks; /* # of tracks per cylinder */
|
||||
u_long d_ncylinders; /* # of data cylinders per unit */
|
||||
u_long d_secpercyl; /* # of data sectors per cylinder */
|
||||
u_long d_secperunit; /* # of data sectors per unit */
|
||||
/*
|
||||
* Spares (bad sector replacements) below
|
||||
* are not counted in d_nsectors or d_secpercyl.
|
||||
* Spare sectors are assumed to be physical sectors
|
||||
* which occupy space at the end of each track and/or cylinder.
|
||||
*/
|
||||
u_short d_sparespertrack; /* # of spare sectors per track */
|
||||
u_short d_sparespercyl; /* # of spare sectors per cylinder */
|
||||
/*
|
||||
* Alternate cylinders include maintenance, replacement,
|
||||
* configuration description areas, etc.
|
||||
*/
|
||||
u_long d_acylinders; /* # of alt. cylinders per unit */
|
||||
|
||||
/* hardware characteristics: */
|
||||
/*
|
||||
* d_interleave, d_trackskew and d_cylskew describe perturbations
|
||||
* in the media format used to compensate for a slow controller.
|
||||
* Interleave is physical sector interleave, set up by the formatter
|
||||
* or controller when formatting. When interleaving is in use,
|
||||
* logically adjacent sectors are not physically contiguous,
|
||||
* but instead are separated by some number of sectors.
|
||||
* It is specified as the ratio of physical sectors traversed
|
||||
* per logical sector. Thus an interleave of 1:1 implies contiguous
|
||||
* layout, while 2:1 implies that logical sector 0 is separated
|
||||
* by one sector from logical sector 1.
|
||||
* d_trackskew is the offset of sector 0 on track N
|
||||
* relative to sector 0 on track N-1 on the same cylinder.
|
||||
* Finally, d_cylskew is the offset of sector 0 on cylinder N
|
||||
* relative to sector 0 on cylinder N-1.
|
||||
*/
|
||||
u_short d_rpm; /* rotational speed */
|
||||
u_short d_interleave; /* hardware sector interleave */
|
||||
u_short d_trackskew; /* sector 0 skew, per track */
|
||||
u_short d_cylskew; /* sector 0 skew, per cylinder */
|
||||
u_long d_headswitch; /* head switch time, usec */
|
||||
u_long d_trkseek; /* track-to-track seek, usec */
|
||||
u_long d_flags; /* generic flags */
|
||||
#define NDDATA 5
|
||||
u_long d_drivedata[NDDATA]; /* drive-type specific information */
|
||||
#define NSPARE 5
|
||||
u_long d_spare[NSPARE]; /* reserved for future use */
|
||||
u_long d_magic2; /* the magic number (again) */
|
||||
u_short d_checksum; /* xor of data incl. partitions */
|
||||
|
||||
/* filesystem and partition information: */
|
||||
u_short d_npartitions; /* number of partitions in following */
|
||||
u_long d_bbsize; /* size of boot area at sn0, bytes */
|
||||
u_long d_sbsize; /* max size of fs superblock, bytes */
|
||||
struct partition { /* the partition table */
|
||||
u_long p_size; /* number of sectors in partition */
|
||||
u_long p_offset; /* starting sector */
|
||||
u_long p_fsize; /* filesystem basic fragment size */
|
||||
u_char p_fstype; /* filesystem type, see below */
|
||||
u_char p_frag; /* filesystem fragments per block */
|
||||
union {
|
||||
u_short cpg; /* UFS: FS cylinders per group */
|
||||
u_short sgs; /* LFS: FS segment shift */
|
||||
} __partition_u1;
|
||||
#define p_cpg __partition_u1.cpg
|
||||
#define p_sgs __partition_u1.sgs
|
||||
u_short p_cpg; /* filesystem cylinders per group */
|
||||
} d_partitions[MAXPARTITIONS]; /* actually may be more */
|
||||
};
|
||||
|
||||
/* d_type values: */
|
||||
#define DTYPE_SMD 1 /* SMD, XSMD; VAX hp/up */
|
||||
#define DTYPE_MSCP 2 /* MSCP */
|
||||
#define DTYPE_DEC 3 /* other DEC (rk, rl) */
|
||||
#define DTYPE_SCSI 4 /* SCSI */
|
||||
#define DTYPE_ESDI 5 /* ESDI interface */
|
||||
#define DTYPE_ST506 6 /* ST506 etc. */
|
||||
#define DTYPE_HPIB 7 /* CS/80 on HP-IB */
|
||||
#define DTYPE_HPFL 8 /* HP Fiber-link */
|
||||
#define DTYPE_FLOPPY 10 /* floppy */
|
||||
|
||||
#ifdef DKTYPENAMES
|
||||
static char *dktypenames[] = {
|
||||
"unknown",
|
||||
"SMD",
|
||||
"MSCP",
|
||||
"old DEC",
|
||||
"SCSI",
|
||||
"ESDI",
|
||||
"ST506",
|
||||
"HP-IB",
|
||||
"HP-FL",
|
||||
"type 9",
|
||||
"floppy",
|
||||
0
|
||||
};
|
||||
#define DKMAXTYPES (sizeof(dktypenames) / sizeof(dktypenames[0]) - 1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Filesystem type and version.
|
||||
* Used to interpret other filesystem-specific
|
||||
* per-partition information.
|
||||
*/
|
||||
#define FS_UNUSED 0 /* unused */
|
||||
#define FS_SWAP 1 /* swap */
|
||||
#define FS_V6 2 /* Sixth Edition */
|
||||
#define FS_V7 3 /* Seventh Edition */
|
||||
#define FS_SYSV 4 /* System V */
|
||||
#define FS_V71K 5 /* V7 with 1K blocks (4.1, 2.9) */
|
||||
#define FS_V8 6 /* Eighth Edition, 4K blocks */
|
||||
#define FS_BSDFFS 7 /* 4.2BSD fast file system */
|
||||
#define FS_MSDOS 8 /* MSDOS file system */
|
||||
#define FS_BSDLFS 9 /* 4.4BSD log-structured file system */
|
||||
#define FS_OTHER 10 /* in use, but unknown/unsupported */
|
||||
#define FS_HPFS 11 /* OS/2 high-performance file system */
|
||||
#define FS_ISO9660 12 /* ISO 9660, normally CD-ROM */
|
||||
#define FS_BOOT 13 /* partition contains bootstrap */
|
||||
|
||||
#ifdef DKTYPENAMES
|
||||
static char *fstypenames[] = {
|
||||
"unused",
|
||||
"swap",
|
||||
"Version 6",
|
||||
"Version 7",
|
||||
"System V",
|
||||
"4.1BSD",
|
||||
"Eighth Edition",
|
||||
"4.2BSD",
|
||||
"MSDOS",
|
||||
"4.4LFS",
|
||||
"unknown",
|
||||
"HPFS",
|
||||
"ISO9660",
|
||||
"boot",
|
||||
0
|
||||
};
|
||||
#define FSMAXTYPES (sizeof(fstypenames) / sizeof(fstypenames[0]) - 1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* flags shared by various drives:
|
||||
*/
|
||||
#define D_REMOVABLE 0x01 /* removable media */
|
||||
#define D_ECC 0x02 /* supports ECC */
|
||||
#define D_BADSECT 0x04 /* supports bad sector forw. */
|
||||
#define D_RAMDISK 0x08 /* disk emulator */
|
||||
#define D_CHAIN 0x10 /* can do back-back transfers */
|
||||
|
||||
/*
|
||||
* Drive data for SMD.
|
||||
*/
|
||||
|
||||
#define d_smdflags d_drivedata[0]
|
||||
#define D_SSE 0x1 /* supports skip sectoring */
|
||||
#define d_mindist d_drivedata[1]
|
||||
#define d_maxdist d_drivedata[2]
|
||||
#define d_sdist d_drivedata[3]
|
||||
|
||||
/*
|
||||
* Drive data for ST506.
|
||||
*/
|
||||
#define d_precompcyl d_drivedata[0]
|
||||
#define d_gap3 d_drivedata[1] /* used only when formatting */
|
||||
|
||||
/*
|
||||
* Drive data for SCSI.
|
||||
*/
|
||||
#define d_blind d_drivedata[0]
|
||||
|
||||
#ifndef LOCORE
|
||||
/*
|
||||
* Structure used to perform a format
|
||||
* or other raw operation, returning data
|
||||
* and/or register values.
|
||||
* Register identification and format
|
||||
* are device- and driver-dependent.
|
||||
*/
|
||||
struct format_op {
|
||||
char *df_buf;
|
||||
int df_count; /* value-result */
|
||||
daddr_t df_startblk;
|
||||
int df_reg[8]; /* result */
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure used internally to retrieve
|
||||
* information about a partition on a disk.
|
||||
*/
|
||||
struct partinfo {
|
||||
struct disklabel *disklab;
|
||||
struct partition *part;
|
||||
};
|
||||
|
||||
/*
|
||||
* Disk-specific ioctls.
|
||||
*/
|
||||
/* get and set disklabel; DIOCGPART used internally */
|
||||
#define DIOCGDINFO _IOR('d', 101, struct disklabel) /* get */
|
||||
#define DIOCSDINFO _IOW('d', 102, struct disklabel) /* set */
|
||||
#define DIOCWDINFO _IOW('d', 103, struct disklabel) /* set, update disk */
|
||||
#define DIOCGPART _IOW('d', 104, struct partinfo) /* get partition */
|
||||
|
||||
/* do format operation, read or write */
|
||||
#define DIOCRFORMAT _IOWR('d', 105, struct format_op)
|
||||
#define DIOCWFORMAT _IOWR('d', 106, struct format_op)
|
||||
|
||||
#define DIOCSSTEP _IOW('d', 107, int) /* set step rate */
|
||||
#define DIOCSRETRIES _IOW('d', 108, int) /* set # of retries */
|
||||
#define DIOCWLABEL _IOW('d', 109, int) /* write en/disable label */
|
||||
|
||||
#define DIOCSBAD _IOW('d', 110, struct dkbad) /* set kernel dkbad */
|
||||
|
||||
#endif LOCORE
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr disktab 5 ,
|
||||
.Xr disklabel 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm disklabel
|
||||
function was introduced in
|
||||
.Bx 4.3 Tahoe .
|
1315
sbin/disklabel/disklabel.c
Normal file
1315
sbin/disklabel/disklabel.c
Normal file
File diff suppressed because it is too large
Load Diff
69
sbin/fastboot/fastboot.8
Normal file
69
sbin/fastboot/fastboot.8
Normal file
@ -0,0 +1,69 @@
|
||||
.\" 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. 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.
|
||||
.\"
|
||||
.\" @(#)fastboot.8 8.1 (Berkeley) 6/5/93
|
||||
.\"
|
||||
.Dd June 5, 1993
|
||||
.Dt FASTBOOT 8
|
||||
.Os BSD 4.2
|
||||
.Sh NAME
|
||||
.Nm fastboot ,
|
||||
.Nm fasthalt
|
||||
.Nd "reboot/halt the system without checking the disks"
|
||||
.Sh SYNOPSIS
|
||||
.Nm fastboot
|
||||
.Op Ar boot-options
|
||||
.Nm fasthalt
|
||||
.Op Ar halt-options
|
||||
.Sh DESCRIPTION
|
||||
.Nm Fastboot
|
||||
and
|
||||
.Nm fasthalt
|
||||
are shell scripts which reboot and halt the system without
|
||||
checking the file systems. This is done by creating a
|
||||
file
|
||||
.Pa /fastboot ,
|
||||
then invoking the
|
||||
.Xr reboot
|
||||
program. The system startup script,
|
||||
.Pa /etc/rc ,
|
||||
looks for this file and, if present, skips the normal
|
||||
invocation of
|
||||
.Xr fsck 8 .
|
||||
.Sh SEE ALSO
|
||||
.Xr halt 8 ,
|
||||
.Xr reboot 8 ,
|
||||
.Xr rc 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command appeared in
|
||||
.Bx 4.2 .
|
277
sbin/ifconfig/ifconfig.8
Normal file
277
sbin/ifconfig/ifconfig.8
Normal file
@ -0,0 +1,277 @@
|
||||
.\" 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. 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.
|
||||
.\"
|
||||
.\" @(#)ifconfig.8 8.4 (Berkeley) 6/1/94
|
||||
.\"
|
||||
.Dd June 1, 1994
|
||||
.Dt IFCONFIG 8
|
||||
.Os BSD 4.2
|
||||
.Sh NAME
|
||||
.Nm ifconfig
|
||||
.Nd configure network interface parameters
|
||||
.Sh SYNOPSIS
|
||||
.Nm ifconfig
|
||||
.Ar interface address_family
|
||||
.Oo
|
||||
.Ar address
|
||||
.Op Ar dest_address
|
||||
.Oc
|
||||
.Op Ar parameters
|
||||
.Nm ifconfig
|
||||
.Ar interface
|
||||
.Op Ar protocol_family
|
||||
.Sh DESCRIPTION
|
||||
.Nm Ifconfig
|
||||
is used to assign an address
|
||||
to a network interface and/or configure
|
||||
network interface parameters.
|
||||
.Nm Ifconfig
|
||||
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 ifconfig:
|
||||
.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 (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 10Mb/s 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 (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 recommeded.
|
||||
The address or protocol families currently
|
||||
supported are
|
||||
.Dq inet ,
|
||||
.Dq iso ,
|
||||
and
|
||||
.Dq ns .
|
||||
.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 ifconfig :
|
||||
.Bl -tag -width dest_addressxx
|
||||
.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 Cm arp
|
||||
Enable the use of the Address Resolution Protocol in mapping
|
||||
between network level addresses and link level addresses (default).
|
||||
This is currently implemented for mapping between
|
||||
.Tn DARPA
|
||||
Internet
|
||||
addresses and 10Mb/s Ethernet addresses.
|
||||
.It Fl arp
|
||||
Disable the use of the Address Resolution Protocol.
|
||||
.It Cm broadcast
|
||||
(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 debug
|
||||
Enable driver dependent debugging code; usually, this turns on
|
||||
extra console error logging.
|
||||
.It Fl debug
|
||||
Disable driver dependent debugging code.
|
||||
.ne 1i
|
||||
.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.
|
||||
.It Cm 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 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 netmask Ar mask
|
||||
(Inet 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.
|
||||
.\" 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
|
||||
(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 trailers
|
||||
Request the use of a ``trailer'' link level encapsulation when
|
||||
sending (default).
|
||||
If a network interface supports
|
||||
.Cm trailers ,
|
||||
the system will, when possible, encapsulate outgoing
|
||||
messages in a manner which minimizes the number of
|
||||
memory to memory copy operations performed by the receiver.
|
||||
On networks that support the Address Resolution Protocol (see
|
||||
.Xr arp 4 ;
|
||||
currently, only 10 Mb/s Ethernet),
|
||||
this flag indicates that the system should request that other
|
||||
systems use trailers when sending to this host.
|
||||
Similarly, trailer encapsulations will be sent to other
|
||||
hosts that have made such requests.
|
||||
Currently used by Internet protocols only.
|
||||
.It Fl trailers
|
||||
Disable the use of a ``trailer'' link level encapsulation.
|
||||
.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. Currently, only used by SLIP.
|
||||
.ne 1i
|
||||
.It Fl link[0-2]
|
||||
Disable special processing at the link level with the specified interface.
|
||||
.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.
|
||||
.El
|
||||
.Pp
|
||||
.Pp
|
||||
.Nm Ifconfig
|
||||
displays the current configuration for a network interface
|
||||
when no optional parameters are supplied.
|
||||
If a protocol family is specified,
|
||||
Ifconfig will report only the details specific to that protocol family.
|
||||
.Pp
|
||||
Only the super-user may modify the configuration of a network interface.
|
||||
.Sh DIAGNOSTICS
|
||||
Messages indicating the specified interface does not exit, 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 netintro 4 ,
|
||||
.Xr rc 8 ,
|
||||
.Xr routed 8 ,
|
||||
.\" .Xr eon 5
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command appeared in
|
||||
.Bx 4.2 .
|
295
sbin/init/init.8
Normal file
295
sbin/init/init.8
Normal file
@ -0,0 +1,295 @@
|
||||
.\" Copyright (c) 1980, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to Berkeley by
|
||||
.\" Donn Seeley at Berkeley Software Design, Inc.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. 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.
|
||||
.\"
|
||||
.\" @(#)init.8 8.6 (Berkeley) 5/26/95
|
||||
.\"
|
||||
.Dd May 26, 1995
|
||||
.Dt INIT 8
|
||||
.Os BSD 4
|
||||
.Sh NAME
|
||||
.Nm init
|
||||
.Nd process control initialization
|
||||
.Sh SYNOPSIS
|
||||
.Nm init
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm init
|
||||
program
|
||||
is the last stage of the boot process.
|
||||
It normally runs the automatic reboot sequence as described in
|
||||
.Xr reboot 8 ,
|
||||
and if this succeeds, begins multi-user operation.
|
||||
If the reboot scripts fail,
|
||||
.Nm init
|
||||
commences single user operation by giving
|
||||
the super-user a shell on the console.
|
||||
The
|
||||
.Nm init
|
||||
program may be passed parameters
|
||||
from the boot program to
|
||||
prevent the system from going multi-user and to instead execute
|
||||
a single user shell without starting the normal daemons.
|
||||
The system is then quiescent for maintenance work and may
|
||||
later be made to go to multi-user by exiting the
|
||||
single-user shell (with ^D).
|
||||
This
|
||||
causes
|
||||
.Nm init
|
||||
to run the
|
||||
.Pa /etc/rc
|
||||
start up command file in fastboot mode (skipping disk checks).
|
||||
.Pp
|
||||
If the
|
||||
.Nm console
|
||||
entry in the
|
||||
.Xr ttys 5
|
||||
file is marked ``insecure'',
|
||||
then
|
||||
.Nm init
|
||||
will require that the superuser password be
|
||||
entered before the system will start a single-user shell.
|
||||
The password check is skipped if the
|
||||
.Nm console
|
||||
is marked as ``secure''.
|
||||
.Pp
|
||||
The kernel runs with four different levels of security.
|
||||
Any superuser process can raise the security level, but only
|
||||
.Nm init
|
||||
can lower it.
|
||||
Security levels are defined as follows:
|
||||
.Bl -tag -width flag
|
||||
.It Ic -1
|
||||
Permanently insecure mode \- always run system in level 0 mode.
|
||||
.It Ic 0
|
||||
Insecure mode \- immutable and append-only flags may be turned off.
|
||||
All devices may be read or written subject to their permissions.
|
||||
.It Ic 1
|
||||
Secure mode \- immutable and append-only flags may not be changed;
|
||||
disks for mounted filesystems,
|
||||
.Pa /dev/mem ,
|
||||
and
|
||||
.Pa /dev/kmem
|
||||
are read-only.
|
||||
The
|
||||
.Xr settimeofday 2
|
||||
system call can only advance the time.
|
||||
.It Ic 2
|
||||
Highly secure mode \- same as secure mode, plus disks are always
|
||||
read-only whether mounted or not.
|
||||
This level precludes tampering with filesystems by unmounting them,
|
||||
but also inhibits running
|
||||
.Xr newfs 8
|
||||
while the system is multi-user.
|
||||
.El
|
||||
.Pp
|
||||
Normally, the system runs in level 0 mode while single user
|
||||
and in level 1 mode while multiuser.
|
||||
If the level 2 mode is desired while running multiuser,
|
||||
it can be set in the startup script
|
||||
.Pa /etc/rc
|
||||
using
|
||||
.Xr sysctl 8 .
|
||||
If it is desired to run the system in level 0 mode while multiuser,
|
||||
the administrator must build a kernel with the variable
|
||||
.Nm securelevel
|
||||
defined in the file
|
||||
.Pa /sys/compile/MACHINE/param.c
|
||||
and initialize it to -1.
|
||||
.Pp
|
||||
In multi-user operation,
|
||||
.Nm init
|
||||
maintains
|
||||
processes for the terminal ports found in the file
|
||||
.Xr ttys 5 .
|
||||
.Nm Init
|
||||
reads this file, and executes the command found in the second field.
|
||||
This command is usually
|
||||
.Xr getty 8 ;
|
||||
.Xr getty
|
||||
opens and initializes the tty line
|
||||
and
|
||||
executes the
|
||||
.Xr login
|
||||
program.
|
||||
The
|
||||
.Xr login
|
||||
program, when a valid user logs in,
|
||||
executes a shell for that user. When this shell
|
||||
dies, either because the user logged out
|
||||
or an abnormal termination occurred (a signal),
|
||||
the
|
||||
.Nm init
|
||||
program wakes up, deletes the user
|
||||
from the
|
||||
.Xr utmp 5
|
||||
file of current users and records the logout in the
|
||||
.Xr wtmp
|
||||
file.
|
||||
The cycle is
|
||||
then restarted by
|
||||
.Nm init
|
||||
executing a new
|
||||
.Xr getty
|
||||
for the line.
|
||||
.pl +1
|
||||
.Pp
|
||||
Line status (on, off, secure, getty, or window information)
|
||||
may be changed in the
|
||||
.Xr ttys
|
||||
file without a reboot by sending the signal
|
||||
.Dv SIGHUP
|
||||
to
|
||||
.Nm init
|
||||
with the command
|
||||
.Dq Li "kill \-s HUP 1" .
|
||||
On receipt of this signal,
|
||||
.Nm init
|
||||
re-reads the
|
||||
.Xr ttys
|
||||
file.
|
||||
When a line is turned off in
|
||||
.Xr ttys ,
|
||||
.Nm init
|
||||
will send a SIGHUP signal to the controlling process
|
||||
for the session associated with the line.
|
||||
For any lines that were previously turned off in the
|
||||
.Xr ttys
|
||||
file and are now on,
|
||||
.Nm init
|
||||
executes a new
|
||||
.Xr getty
|
||||
to enable a new login.
|
||||
If the getty or window field for a line is changed,
|
||||
the change takes effect at the end of the current
|
||||
login session (e.g., the next time
|
||||
.Nm init
|
||||
starts a process on the line).
|
||||
If a line is commented out or deleted from
|
||||
.Xr ttys ,
|
||||
.Nm init
|
||||
will not do anything at all to that line.
|
||||
However, it will complain that the relationship between lines
|
||||
in the
|
||||
.Xr ttys
|
||||
file and records in the
|
||||
.Xr utmp
|
||||
file is out of sync,
|
||||
so this practice is not recommended.
|
||||
.Pp
|
||||
.Nm Init
|
||||
will terminate multi-user operations and resume single-user mode
|
||||
if sent a terminate
|
||||
.Pq Dv TERM
|
||||
signal, for example,
|
||||
.Dq Li "kill \-s TERM 1" .
|
||||
If there are processes outstanding that are deadlocked (because of
|
||||
hardware or software failure),
|
||||
.Xr init
|
||||
will not wait for them all to die (which might take forever), but
|
||||
will time out after 30 seconds and print a warning message.
|
||||
.Pp
|
||||
.Nm Init
|
||||
will cease creating new
|
||||
.Xr getty Ns 's
|
||||
and allow the system to slowly die away, if it is sent a terminal stop
|
||||
.Pq Dv TSTP
|
||||
signal, i.e.
|
||||
.Dq Li "kill \-s TSTP 1" .
|
||||
A later hangup will resume full
|
||||
multi-user operations, or a terminate will start a single user shell.
|
||||
This hook is used by
|
||||
.Xr reboot 8
|
||||
and
|
||||
.Xr halt 8 .
|
||||
.Pp
|
||||
The role of
|
||||
.Nm init
|
||||
is so critical that if it dies, the system will reboot itself
|
||||
automatically.
|
||||
If, at bootstrap time, the
|
||||
.Xr init
|
||||
process cannot be located, the system will panic with the message
|
||||
``panic: "init died (signal %d, exit %d)''.
|
||||
.Sh DIAGNOSTICS
|
||||
.Bl -diag
|
||||
.It "getty repeating too quickly on port %s, sleeping"
|
||||
A process being started to service a line is exiting quickly
|
||||
each time it is started.
|
||||
This is often caused by a ringing or noisy terminal line.
|
||||
.Em "Init will sleep for 10 seconds" ,
|
||||
.Em "then continue trying to start the process" .
|
||||
.Pp
|
||||
.It "some processes would not die; ps axl advised."
|
||||
A process
|
||||
is hung and could not be killed when the system was shutting down.
|
||||
This condition is usually caused by a process
|
||||
that is stuck in a device driver because of
|
||||
a persistent device error condition.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width /var/log/wtmp -compact
|
||||
.It Pa /dev/console
|
||||
System console device.
|
||||
.It Pa /dev/tty*
|
||||
Terminal ports found in
|
||||
.Xr ttys .
|
||||
.It Pa /var/run/utmp
|
||||
Record of Current users on the system.
|
||||
.It Pa /var/log/wtmp
|
||||
Record of all logins and logouts.
|
||||
.It Pa /etc/ttys
|
||||
The terminal initialization information file.
|
||||
.It Pa /etc/rc
|
||||
System startup commands.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr login 1 ,
|
||||
.Xr kill 1 ,
|
||||
.Xr sh 1 ,
|
||||
.Xr ttys 5 ,
|
||||
.Xr crash 8 ,
|
||||
.Xr getty 8 ,
|
||||
.Xr rc 8 ,
|
||||
.Xr reboot 8 ,
|
||||
.Xr halt 8 ,
|
||||
.Xr shutdown 8
|
||||
.Sh HISTORY
|
||||
A
|
||||
.Nm
|
||||
command appeared in
|
||||
.At v6 .
|
||||
.Sh BUGS
|
||||
Systems without
|
||||
.Xr sysctl
|
||||
behave as though they have security level \-1.
|
1297
sbin/init/init.c
Normal file
1297
sbin/init/init.c
Normal file
File diff suppressed because it is too large
Load Diff
328
sbin/ping/ping.8
Normal file
328
sbin/ping/ping.8
Normal file
@ -0,0 +1,328 @@
|
||||
.\" Copyright (c) 1985, 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. 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.
|
||||
.\"
|
||||
.\" @(#)ping.8 8.3 (Berkeley) 4/28/95
|
||||
.\"
|
||||
.Dd April 28, 1995
|
||||
.Dt PING 8
|
||||
.Os BSD 4.3
|
||||
.Sh NAME
|
||||
.Nm ping
|
||||
.Nd send
|
||||
.Tn ICMP ECHO_REQUEST
|
||||
packets to network hosts
|
||||
.Sh SYNOPSIS
|
||||
.Nm ping
|
||||
.Op Fl Rdfnqrv
|
||||
.Op Fl c Ar count
|
||||
.Op Fl i Ar wait
|
||||
.Op Fl l Ar preload
|
||||
.Op Fl p Ar pattern
|
||||
.Op Fl s Ar packetsize
|
||||
.Ar host
|
||||
.Sh DESCRIPTION
|
||||
.Nm Ping
|
||||
uses the
|
||||
.Tn ICMP
|
||||
protocol's mandatory
|
||||
.Tn ECHO_REQUEST
|
||||
datagram to elicit an
|
||||
.Tn ICMP ECHO_RESPONSE
|
||||
from a host or gateway.
|
||||
.Tn ECHO_REQUEST
|
||||
datagrams (``pings'') have an IP and
|
||||
.Tn ICMP
|
||||
header,
|
||||
followed by a
|
||||
.Dq struct timeval
|
||||
and then an arbitrary number of ``pad'' bytes used to fill out the
|
||||
packet.
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl c Ar count
|
||||
Stop after sending (and receiving)
|
||||
.Ar count
|
||||
.Tn ECHO_RESPONSE
|
||||
packets.
|
||||
.It Fl d
|
||||
Set the
|
||||
.Dv SO_DEBUG
|
||||
option on the socket being used.
|
||||
.It Fl f
|
||||
Flood ping.
|
||||
Outputs packets as fast as they come back or one hundred times per second,
|
||||
whichever is more.
|
||||
For every
|
||||
.Tn ECHO_REQUEST
|
||||
sent a period ``.'' is printed, while for every
|
||||
.Tn ECHO_REPLY
|
||||
received a backspace is printed.
|
||||
This provides a rapid display of how many packets are being dropped.
|
||||
Only the super-user may use this option.
|
||||
.Bf -emphasis
|
||||
This can be very hard on a network and should be used with caution.
|
||||
.Ef
|
||||
.It Fl i Ar wait
|
||||
Wait
|
||||
.Ar wait
|
||||
seconds
|
||||
.Em between sending each packet .
|
||||
The default is to wait for one second between each packet.
|
||||
This option is incompatible with the
|
||||
.Fl f
|
||||
option.
|
||||
.It Fl l Ar preload
|
||||
If
|
||||
.Ar preload
|
||||
is specified,
|
||||
.Nm ping
|
||||
sends that many packets as fast as possible before falling into its normal
|
||||
mode of behavior.
|
||||
.It Fl n
|
||||
Numeric output only.
|
||||
No attempt will be made to lookup symbolic names for host addresses.
|
||||
.It Fl p Ar pattern
|
||||
You may specify up to 16 ``pad'' bytes to fill out the packet you send.
|
||||
This is useful for diagnosing data-dependent problems in a network.
|
||||
For example,
|
||||
.Dq Li \-p ff
|
||||
will cause the sent packet to be filled with all
|
||||
ones.
|
||||
.It Fl q
|
||||
Quiet output.
|
||||
Nothing is displayed except the summary lines at startup time and
|
||||
when finished.
|
||||
.It Fl R
|
||||
Record route.
|
||||
Includes the
|
||||
.Tn RECORD_ROUTE
|
||||
option in the
|
||||
.Tn ECHO_REQUEST
|
||||
packet and displays
|
||||
the route buffer on returned packets.
|
||||
Note that the IP header is only large enough for nine such routes.
|
||||
Many hosts ignore or discard this option.
|
||||
.It Fl r
|
||||
Bypass the normal routing tables and send directly to a host on an attached
|
||||
network.
|
||||
If the host is not on a directly-attached network, an error is returned.
|
||||
This option can be used to ping a local host through an interface
|
||||
that has no route through it (e.g., after the interface was dropped by
|
||||
.Xr routed 8 ) .
|
||||
.It Fl s Ar packetsize
|
||||
Specifies the number of data bytes to be sent.
|
||||
The default is 56, which translates into 64
|
||||
.Tn ICMP
|
||||
data bytes when combined
|
||||
with the 8 bytes of
|
||||
.Tn ICMP
|
||||
header data.
|
||||
.It Fl v
|
||||
Verbose output.
|
||||
.Tn ICMP
|
||||
packets other than
|
||||
.Tn ECHO_RESPONSE
|
||||
that are received are listed.
|
||||
.El
|
||||
.Pp
|
||||
When using
|
||||
.Nm ping
|
||||
for fault isolation, it should first be run on the local host, to verify
|
||||
that the local network interface is up and running.
|
||||
Then, hosts and gateways further and further away should be ``pinged''.
|
||||
Round-trip times and packet loss statistics are computed.
|
||||
If duplicate packets are received, they are not included in the packet
|
||||
loss calculation, although the round trip time of these packets is used
|
||||
in calculating the minimum/average/maximum round-trip time numbers.
|
||||
When the specified number of packets have been sent (and received) or
|
||||
if the program is terminated with a
|
||||
.Dv SIGINT ,
|
||||
a brief summary is displayed.
|
||||
.Pp
|
||||
This program is intended for use in network testing, measurement and
|
||||
management.
|
||||
Because of the load it can impose on the network, it is unwise to use
|
||||
.Nm ping
|
||||
during normal operations or from automated scripts.
|
||||
.Sh ICMP PACKET DETAILS
|
||||
An IP header without options is 20 bytes.
|
||||
An
|
||||
.Tn ICMP
|
||||
.Tn ECHO_REQUEST
|
||||
packet contains an additional 8 bytes worth
|
||||
of
|
||||
.Tn ICMP
|
||||
header followed by an arbitrary amount of data.
|
||||
When a
|
||||
.Ar packetsize
|
||||
is given, this indicated the size of this extra piece of data (the
|
||||
default is 56).
|
||||
Thus the amount of data received inside of an IP packet of type
|
||||
.Tn ICMP
|
||||
.Tn ECHO_REPLY
|
||||
will always be 8 bytes more than the requested data space
|
||||
(the
|
||||
.Tn ICMP
|
||||
header).
|
||||
.Pp
|
||||
If the data space is at least eight bytes large,
|
||||
.Nm ping
|
||||
uses the first eight bytes of this space to include a timestamp which
|
||||
it uses in the computation of round trip times.
|
||||
If less than eight bytes of pad are specified, no round trip times are
|
||||
given.
|
||||
.Sh DUPLICATE AND DAMAGED PACKETS
|
||||
.Nm Ping
|
||||
will report duplicate and damaged packets.
|
||||
Duplicate packets should never occur, and seem to be caused by
|
||||
inappropriate link-level retransmissions.
|
||||
Duplicates may occur in many situations and are rarely (if ever) a
|
||||
good sign, although the presence of low levels of duplicates may not
|
||||
always be cause for alarm.
|
||||
.Pp
|
||||
Damaged packets are obviously serious cause for alarm and often
|
||||
indicate broken hardware somewhere in the
|
||||
.Nm ping
|
||||
packet's path (in the network or in the hosts).
|
||||
.Sh TRYING DIFFERENT DATA PATTERNS
|
||||
The (inter)network layer should never treat packets differently depending
|
||||
on the data contained in the data portion.
|
||||
Unfortunately, data-dependent problems have been known to sneak into
|
||||
networks and remain undetected for long periods of time.
|
||||
In many cases the particular pattern that will have problems is something
|
||||
that doesn't have sufficient ``transitions'', such as all ones or all
|
||||
zeros, or a pattern right at the edge, such as almost all zeros.
|
||||
It isn't necessarily enough to specify a data pattern of all zeros (for
|
||||
example) on the command line because the pattern that is of interest is
|
||||
at the data link level, and the relationship between what you type and
|
||||
what the controllers transmit can be complicated.
|
||||
.Pp
|
||||
This means that if you have a data-dependent problem you will probably
|
||||
have to do a lot of testing to find it.
|
||||
If you are lucky, you may manage to find a file that either can't be sent
|
||||
across your network or that takes much longer to transfer than other
|
||||
similar length files.
|
||||
You can then examine this file for repeated patterns that you can test
|
||||
using the
|
||||
.Fl p
|
||||
option of
|
||||
.Nm ping .
|
||||
.Sh TTL DETAILS
|
||||
The
|
||||
.Tn TTL
|
||||
value of an IP packet represents the maximum number of IP routers
|
||||
that the packet can go through before being thrown away.
|
||||
In current practice you can expect each router in the Internet to decrement
|
||||
the
|
||||
.Tn TTL
|
||||
field by exactly one.
|
||||
.Pp
|
||||
The
|
||||
.Tn TCP/IP
|
||||
specification states that the
|
||||
.Tn TTL
|
||||
field for
|
||||
.Tn TCP
|
||||
packets should
|
||||
be set to 60, but many systems use smaller values (4.3
|
||||
.Tn BSD
|
||||
uses 30, 4.2 used
|
||||
15).
|
||||
.Pp
|
||||
The maximum possible value of this field is 255, and most Unix systems set
|
||||
the
|
||||
.Tn TTL
|
||||
field of
|
||||
.Tn ICMP ECHO_REQUEST
|
||||
packets to 255.
|
||||
This is why you will find you can ``ping'' some hosts, but not reach them
|
||||
with
|
||||
.Xr telnet 1
|
||||
or
|
||||
.Xr ftp 1 .
|
||||
.Pp
|
||||
In normal operation ping prints the ttl value from the packet it receives.
|
||||
When a remote system receives a ping packet, it can do one of three things
|
||||
with the
|
||||
.Tn TTL
|
||||
field in its response:
|
||||
.Bl -bullet
|
||||
.It
|
||||
Not change it; this is what Berkeley Unix systems did before the
|
||||
.Bx 4.3 tahoe
|
||||
release.
|
||||
In this case the
|
||||
.Tn TTL
|
||||
value in the received packet will be 255 minus the
|
||||
number of routers in the round-trip path.
|
||||
.It
|
||||
Set it to 255; this is what current Berkeley Unix systems do.
|
||||
In this case the
|
||||
.Tn TTL
|
||||
value in the received packet will be 255 minus the
|
||||
number of routers in the path
|
||||
.Xr from
|
||||
the remote system
|
||||
.Em to
|
||||
the
|
||||
.Nm ping Ns Em ing
|
||||
host.
|
||||
.It
|
||||
Set it to some other value.
|
||||
Some machines use the same value for
|
||||
.Tn ICMP
|
||||
packets that they use for
|
||||
.Tn TCP
|
||||
packets, for example either 30 or 60.
|
||||
Others may use completely wild values.
|
||||
.El
|
||||
.Sh BUGS
|
||||
Many Hosts and Gateways ignore the
|
||||
.Tn RECORD_ROUTE
|
||||
option.
|
||||
.Pp
|
||||
The maximum IP header length is too small for options like
|
||||
.Tn RECORD_ROUTE
|
||||
to
|
||||
be completely useful.
|
||||
There's not much that that can be done about this, however.
|
||||
.Pp
|
||||
Flood pinging is not recommended in general, and flood pinging the
|
||||
broadcast address should only be done under very controlled conditions.
|
||||
.Sh SEE ALSO
|
||||
.Xr netstat 1 ,
|
||||
.Xr ifconfig 8 ,
|
||||
.Xr routed 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command appeared in
|
||||
.Bx 4.3 .
|
986
sbin/ping/ping.c
Normal file
986
sbin/ping/ping.c
Normal file
@ -0,0 +1,986 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Mike Muuss.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1989, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)ping.c 8.3 (Berkeley) 4/28/95";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* P I N G . C
|
||||
*
|
||||
* Using the InterNet Control Message Protocol (ICMP) "ECHO" facility,
|
||||
* measure round-trip-delays and packet loss across network paths.
|
||||
*
|
||||
* Author -
|
||||
* Mike Muuss
|
||||
* U. S. Army Ballistic Research Laboratory
|
||||
* December, 1983
|
||||
*
|
||||
* Status -
|
||||
* Public Domain. Distribution Unlimited.
|
||||
* Bugs -
|
||||
* More statistics could always be gathered.
|
||||
* This program has to run SUID to ROOT to access the ICMP socket.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/signal.h>
|
||||
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_icmp.h>
|
||||
#include <netinet/ip_var.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#define DEFDATALEN (64 - 8) /* default data length */
|
||||
#define MAXIPLEN 60
|
||||
#define MAXICMPLEN 76
|
||||
#define MAXPACKET (65536 - 60 - 8)/* max packet size */
|
||||
#define MAXWAIT 10 /* max seconds to wait for response */
|
||||
#define NROUTES 9 /* number of record route slots */
|
||||
|
||||
#define A(bit) rcvd_tbl[(bit)>>3] /* identify byte in array */
|
||||
#define B(bit) (1 << ((bit) & 0x07)) /* identify bit in byte */
|
||||
#define SET(bit) (A(bit) |= B(bit))
|
||||
#define CLR(bit) (A(bit) &= (~B(bit)))
|
||||
#define TST(bit) (A(bit) & B(bit))
|
||||
|
||||
/* various options */
|
||||
int options;
|
||||
#define F_FLOOD 0x001
|
||||
#define F_INTERVAL 0x002
|
||||
#define F_NUMERIC 0x004
|
||||
#define F_PINGFILLED 0x008
|
||||
#define F_QUIET 0x010
|
||||
#define F_RROUTE 0x020
|
||||
#define F_SO_DEBUG 0x040
|
||||
#define F_SO_DONTROUTE 0x080
|
||||
#define F_VERBOSE 0x100
|
||||
|
||||
/*
|
||||
* MAX_DUP_CHK is the number of bits in received table, i.e. the maximum
|
||||
* number of received sequence numbers we can keep track of. Change 128
|
||||
* to 8192 for complete accuracy...
|
||||
*/
|
||||
#define MAX_DUP_CHK (8 * 128)
|
||||
int mx_dup_ck = MAX_DUP_CHK;
|
||||
char rcvd_tbl[MAX_DUP_CHK / 8];
|
||||
|
||||
struct sockaddr whereto; /* who to ping */
|
||||
int datalen = DEFDATALEN;
|
||||
int s; /* socket file descriptor */
|
||||
u_char outpack[MAXPACKET];
|
||||
char BSPACE = '\b'; /* characters written for flood */
|
||||
char DOT = '.';
|
||||
char *hostname;
|
||||
int ident; /* process id to identify our packets */
|
||||
|
||||
/* counters */
|
||||
long npackets; /* max packets to transmit */
|
||||
long nreceived; /* # of packets we got back */
|
||||
long nrepeats; /* number of duplicates */
|
||||
long ntransmitted; /* sequence # for outbound packets = #sent */
|
||||
int interval = 1; /* interval between packets */
|
||||
|
||||
/* timing */
|
||||
int timing; /* flag to do timing */
|
||||
double tmin = 999999999.0; /* minimum round trip time */
|
||||
double tmax = 0.0; /* maximum round trip time */
|
||||
double tsum = 0.0; /* sum of all times, for doing average */
|
||||
|
||||
char *pr_addr();
|
||||
void catcher(), finish();
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
extern int errno, optind;
|
||||
extern char *optarg;
|
||||
struct timeval timeout;
|
||||
struct hostent *hp;
|
||||
struct sockaddr_in *to;
|
||||
struct protoent *proto;
|
||||
register int i;
|
||||
int ch, fdmask, hold, packlen, preload;
|
||||
u_char *datap, *packet;
|
||||
char *target, hnamebuf[MAXHOSTNAMELEN], *malloc();
|
||||
#ifdef IP_OPTIONS
|
||||
char rspace[3 + 4 * NROUTES + 1]; /* record route space */
|
||||
#endif
|
||||
|
||||
preload = 0;
|
||||
datap = &outpack[8 + sizeof(struct timeval)];
|
||||
while ((ch = getopt(argc, argv, "Rc:dfh:i:l:np:qrs:v")) != EOF)
|
||||
switch(ch) {
|
||||
case 'c':
|
||||
npackets = atoi(optarg);
|
||||
if (npackets <= 0) {
|
||||
(void)fprintf(stderr,
|
||||
"ping: bad number of packets to transmit.\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
options |= F_SO_DEBUG;
|
||||
break;
|
||||
case 'f':
|
||||
if (getuid()) {
|
||||
(void)fprintf(stderr,
|
||||
"ping: %s\n", strerror(EPERM));
|
||||
exit(1);
|
||||
}
|
||||
options |= F_FLOOD;
|
||||
setbuf(stdout, (char *)NULL);
|
||||
break;
|
||||
case 'i': /* wait between sending packets */
|
||||
interval = atoi(optarg);
|
||||
if (interval <= 0) {
|
||||
(void)fprintf(stderr,
|
||||
"ping: bad timing interval.\n");
|
||||
exit(1);
|
||||
}
|
||||
options |= F_INTERVAL;
|
||||
break;
|
||||
case 'l':
|
||||
preload = atoi(optarg);
|
||||
if (preload < 0) {
|
||||
(void)fprintf(stderr,
|
||||
"ping: bad preload value.\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
options |= F_NUMERIC;
|
||||
break;
|
||||
case 'p': /* fill buffer with user pattern */
|
||||
options |= F_PINGFILLED;
|
||||
fill((char *)datap, optarg);
|
||||
break;
|
||||
case 'q':
|
||||
options |= F_QUIET;
|
||||
break;
|
||||
case 'R':
|
||||
options |= F_RROUTE;
|
||||
break;
|
||||
case 'r':
|
||||
options |= F_SO_DONTROUTE;
|
||||
break;
|
||||
case 's': /* size of packet to send */
|
||||
datalen = atoi(optarg);
|
||||
if (datalen > MAXPACKET) {
|
||||
(void)fprintf(stderr,
|
||||
"ping: packet size too large.\n");
|
||||
exit(1);
|
||||
}
|
||||
if (datalen <= 0) {
|
||||
(void)fprintf(stderr,
|
||||
"ping: illegal packet size.\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
options |= F_VERBOSE;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc != 1)
|
||||
usage();
|
||||
target = *argv;
|
||||
|
||||
memset(&whereto, 0, sizeof(struct sockaddr));
|
||||
to = (struct sockaddr_in *)&whereto;
|
||||
to->sin_family = AF_INET;
|
||||
to->sin_addr.s_addr = inet_addr(target);
|
||||
if (to->sin_addr.s_addr != (u_int)-1)
|
||||
hostname = target;
|
||||
else {
|
||||
hp = gethostbyname(target);
|
||||
if (!hp) {
|
||||
(void)fprintf(stderr,
|
||||
"ping: unknown host %s\n", target);
|
||||
exit(1);
|
||||
}
|
||||
to->sin_family = hp->h_addrtype;
|
||||
memmove(&to->sin_addr, hp->h_addr, hp->h_length);
|
||||
(void)strncpy(hnamebuf, hp->h_name, sizeof(hnamebuf) - 1);
|
||||
hostname = hnamebuf;
|
||||
}
|
||||
|
||||
if (options & F_FLOOD && options & F_INTERVAL) {
|
||||
(void)fprintf(stderr,
|
||||
"ping: -f and -i incompatible options.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (datalen >= sizeof(struct timeval)) /* can we time transfer */
|
||||
timing = 1;
|
||||
packlen = datalen + MAXIPLEN + MAXICMPLEN;
|
||||
if (!(packet = (u_char *)malloc((u_int)packlen))) {
|
||||
(void)fprintf(stderr, "ping: out of memory.\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!(options & F_PINGFILLED))
|
||||
for (i = 8; i < datalen; ++i)
|
||||
*datap++ = i;
|
||||
|
||||
ident = getpid() & 0xFFFF;
|
||||
|
||||
if (!(proto = getprotobyname("icmp"))) {
|
||||
(void)fprintf(stderr, "ping: unknown protocol icmp.\n");
|
||||
exit(1);
|
||||
}
|
||||
if ((s = socket(AF_INET, SOCK_RAW, proto->p_proto)) < 0) {
|
||||
perror("ping: socket");
|
||||
exit(1);
|
||||
}
|
||||
hold = 1;
|
||||
if (options & F_SO_DEBUG)
|
||||
(void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&hold,
|
||||
sizeof(hold));
|
||||
if (options & F_SO_DONTROUTE)
|
||||
(void)setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&hold,
|
||||
sizeof(hold));
|
||||
|
||||
/* record route option */
|
||||
if (options & F_RROUTE) {
|
||||
#ifdef IP_OPTIONS
|
||||
rspace[IPOPT_OPTVAL] = IPOPT_RR;
|
||||
rspace[IPOPT_OLEN] = sizeof(rspace)-1;
|
||||
rspace[IPOPT_OFFSET] = IPOPT_MINOFF;
|
||||
if (setsockopt(s, IPPROTO_IP, IP_OPTIONS, rspace,
|
||||
sizeof(rspace)) < 0) {
|
||||
perror("ping: record route");
|
||||
exit(1);
|
||||
}
|
||||
#else
|
||||
(void)fprintf(stderr,
|
||||
"ping: record route not available in this implementation.\n");
|
||||
exit(1);
|
||||
#endif /* IP_OPTIONS */
|
||||
}
|
||||
|
||||
/*
|
||||
* When pinging the broadcast address, you can get a lot of answers.
|
||||
* Doing something so evil is useful if you are trying to stress the
|
||||
* ethernet, or just want to fill the arp cache to get some stuff for
|
||||
* /etc/ethers.
|
||||
*/
|
||||
hold = 48 * 1024;
|
||||
(void)setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&hold,
|
||||
sizeof(hold));
|
||||
|
||||
if (to->sin_family == AF_INET)
|
||||
(void)printf("PING %s (%s): %d data bytes\n", hostname,
|
||||
inet_ntoa(*(struct in_addr *)&to->sin_addr.s_addr),
|
||||
datalen);
|
||||
else
|
||||
(void)printf("PING %s: %d data bytes\n", hostname, datalen);
|
||||
|
||||
(void)signal(SIGINT, finish);
|
||||
(void)signal(SIGALRM, catcher);
|
||||
|
||||
while (preload--) /* fire off them quickies */
|
||||
pinger();
|
||||
|
||||
if ((options & F_FLOOD) == 0)
|
||||
catcher(); /* start things going */
|
||||
|
||||
for (;;) {
|
||||
struct sockaddr_in from;
|
||||
register int cc;
|
||||
int fromlen;
|
||||
|
||||
if (options & F_FLOOD) {
|
||||
pinger();
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 10000;
|
||||
fdmask = 1 << s;
|
||||
if (select(s + 1, (fd_set *)&fdmask, (fd_set *)NULL,
|
||||
(fd_set *)NULL, &timeout) < 1)
|
||||
continue;
|
||||
}
|
||||
fromlen = sizeof(from);
|
||||
if ((cc = recvfrom(s, (char *)packet, packlen, 0,
|
||||
(struct sockaddr *)&from, &fromlen)) < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
perror("ping: recvfrom");
|
||||
continue;
|
||||
}
|
||||
pr_pack((char *)packet, cc, &from);
|
||||
if (npackets && nreceived >= npackets)
|
||||
break;
|
||||
}
|
||||
finish();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* catcher --
|
||||
* This routine causes another PING to be transmitted, and then
|
||||
* schedules another SIGALRM for 1 second from now.
|
||||
*
|
||||
* bug --
|
||||
* Our sense of time will slowly skew (i.e., packets will not be
|
||||
* launched exactly at 1-second intervals). This does not affect the
|
||||
* quality of the delay and loss statistics.
|
||||
*/
|
||||
void
|
||||
catcher()
|
||||
{
|
||||
int waittime;
|
||||
|
||||
pinger();
|
||||
(void)signal(SIGALRM, catcher);
|
||||
if (!npackets || ntransmitted < npackets)
|
||||
alarm((u_int)interval);
|
||||
else {
|
||||
if (nreceived) {
|
||||
waittime = 2 * tmax / 1000;
|
||||
if (!waittime)
|
||||
waittime = 1;
|
||||
} else
|
||||
waittime = MAXWAIT;
|
||||
(void)signal(SIGALRM, finish);
|
||||
(void)alarm((u_int)waittime);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* pinger --
|
||||
* Compose and transmit an ICMP ECHO REQUEST packet. The IP packet
|
||||
* will be added on by the kernel. The ID field is our UNIX process ID,
|
||||
* and the sequence number is an ascending integer. The first 8 bytes
|
||||
* of the data portion are used to hold a UNIX "timeval" struct in VAX
|
||||
* byte-order, to compute the round-trip time.
|
||||
*/
|
||||
pinger()
|
||||
{
|
||||
register struct icmp *icp;
|
||||
register int cc;
|
||||
int i;
|
||||
|
||||
icp = (struct icmp *)outpack;
|
||||
icp->icmp_type = ICMP_ECHO;
|
||||
icp->icmp_code = 0;
|
||||
icp->icmp_cksum = 0;
|
||||
icp->icmp_seq = ntransmitted++;
|
||||
icp->icmp_id = ident; /* ID */
|
||||
|
||||
CLR(icp->icmp_seq % mx_dup_ck);
|
||||
|
||||
if (timing)
|
||||
(void)gettimeofday((struct timeval *)&outpack[8],
|
||||
(struct timezone *)NULL);
|
||||
|
||||
cc = datalen + 8; /* skips ICMP portion */
|
||||
|
||||
/* compute ICMP checksum here */
|
||||
icp->icmp_cksum = in_cksum((u_short *)icp, cc);
|
||||
|
||||
i = sendto(s, (char *)outpack, cc, 0, &whereto,
|
||||
sizeof(struct sockaddr));
|
||||
|
||||
if (i < 0 || i != cc) {
|
||||
if (i < 0)
|
||||
perror("ping: sendto");
|
||||
(void)printf("ping: wrote %s %d chars, ret=%d\n",
|
||||
hostname, cc, i);
|
||||
}
|
||||
if (!(options & F_QUIET) && options & F_FLOOD)
|
||||
(void)write(STDOUT_FILENO, &DOT, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* pr_pack --
|
||||
* Print out the packet, if it came from us. This logic is necessary
|
||||
* because ALL readers of the ICMP socket get a copy of ALL ICMP packets
|
||||
* which arrive ('tis only fair). This permits multiple copies of this
|
||||
* program to be run without having intermingled output (or statistics!).
|
||||
*/
|
||||
pr_pack(buf, cc, from)
|
||||
char *buf;
|
||||
int cc;
|
||||
struct sockaddr_in *from;
|
||||
{
|
||||
register struct icmp *icp;
|
||||
register u_long l;
|
||||
register int i, j;
|
||||
register u_char *cp,*dp;
|
||||
static int old_rrlen;
|
||||
static char old_rr[MAX_IPOPTLEN];
|
||||
struct ip *ip;
|
||||
struct timeval tv, *tp;
|
||||
double triptime;
|
||||
int hlen, dupflag;
|
||||
|
||||
(void)gettimeofday(&tv, (struct timezone *)NULL);
|
||||
|
||||
/* Check the IP header */
|
||||
ip = (struct ip *)buf;
|
||||
hlen = ip->ip_hl << 2;
|
||||
if (cc < hlen + ICMP_MINLEN) {
|
||||
if (options & F_VERBOSE)
|
||||
(void)fprintf(stderr,
|
||||
"ping: packet too short (%d bytes) from %s\n", cc,
|
||||
inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now the ICMP part */
|
||||
cc -= hlen;
|
||||
icp = (struct icmp *)(buf + hlen);
|
||||
if (icp->icmp_type == ICMP_ECHOREPLY) {
|
||||
if (icp->icmp_id != ident)
|
||||
return; /* 'Twas not our ECHO */
|
||||
++nreceived;
|
||||
if (timing) {
|
||||
#ifndef icmp_data
|
||||
tp = (struct timeval *)&icp->icmp_ip;
|
||||
#else
|
||||
tp = (struct timeval *)icp->icmp_data;
|
||||
#endif
|
||||
tvsub(&tv, tp);
|
||||
triptime = ((double)tv.tv_sec) * 1000.0 +
|
||||
((double)tv.tv_usec) / 1000.0;
|
||||
tsum += triptime;
|
||||
if (triptime < tmin)
|
||||
tmin = triptime;
|
||||
if (triptime > tmax)
|
||||
tmax = triptime;
|
||||
}
|
||||
|
||||
if (TST(icp->icmp_seq % mx_dup_ck)) {
|
||||
++nrepeats;
|
||||
--nreceived;
|
||||
dupflag = 1;
|
||||
} else {
|
||||
SET(icp->icmp_seq % mx_dup_ck);
|
||||
dupflag = 0;
|
||||
}
|
||||
|
||||
if (options & F_QUIET)
|
||||
return;
|
||||
|
||||
if (options & F_FLOOD)
|
||||
(void)write(STDOUT_FILENO, &BSPACE, 1);
|
||||
else {
|
||||
(void)printf("%d bytes from %s: icmp_seq=%u", cc,
|
||||
inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr),
|
||||
icp->icmp_seq);
|
||||
(void)printf(" ttl=%d", ip->ip_ttl);
|
||||
if (timing)
|
||||
(void)printf(" time=%g ms", triptime);
|
||||
if (dupflag)
|
||||
(void)printf(" (DUP!)");
|
||||
/* check the data */
|
||||
cp = (u_char*)&icp->icmp_data[8];
|
||||
dp = &outpack[8 + sizeof(struct timeval)];
|
||||
for (i = 8; i < datalen; ++i, ++cp, ++dp) {
|
||||
if (*cp != *dp) {
|
||||
(void)printf("\nwrong data byte #%d should be 0x%x but was 0x%x",
|
||||
i, *dp, *cp);
|
||||
cp = (u_char*)&icp->icmp_data[0];
|
||||
for (i = 8; i < datalen; ++i, ++cp) {
|
||||
if ((i % 32) == 8)
|
||||
(void)printf("\n\t");
|
||||
(void)printf("%x ", *cp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* We've got something other than an ECHOREPLY */
|
||||
if (!(options & F_VERBOSE))
|
||||
return;
|
||||
(void)printf("%d bytes from %s: ", cc,
|
||||
pr_addr(from->sin_addr.s_addr));
|
||||
pr_icmph(icp);
|
||||
}
|
||||
|
||||
/* Display any IP options */
|
||||
cp = (u_char *)buf + sizeof(struct ip);
|
||||
|
||||
for (; hlen > (int)sizeof(struct ip); --hlen, ++cp)
|
||||
switch (*cp) {
|
||||
case IPOPT_EOL:
|
||||
hlen = 0;
|
||||
break;
|
||||
case IPOPT_LSRR:
|
||||
(void)printf("\nLSRR: ");
|
||||
hlen -= 2;
|
||||
j = *++cp;
|
||||
++cp;
|
||||
if (j > IPOPT_MINOFF)
|
||||
for (;;) {
|
||||
l = *++cp;
|
||||
l = (l<<8) + *++cp;
|
||||
l = (l<<8) + *++cp;
|
||||
l = (l<<8) + *++cp;
|
||||
if (l == 0)
|
||||
(void)printf("\t0.0.0.0");
|
||||
else
|
||||
(void)printf("\t%s", pr_addr(ntohl(l)));
|
||||
hlen -= 4;
|
||||
j -= 4;
|
||||
if (j <= IPOPT_MINOFF)
|
||||
break;
|
||||
(void)putchar('\n');
|
||||
}
|
||||
break;
|
||||
case IPOPT_RR:
|
||||
j = *++cp; /* get length */
|
||||
i = *++cp; /* and pointer */
|
||||
hlen -= 2;
|
||||
if (i > j)
|
||||
i = j;
|
||||
i -= IPOPT_MINOFF;
|
||||
if (i <= 0)
|
||||
continue;
|
||||
if (i == old_rrlen
|
||||
&& cp == (u_char *)buf + sizeof(struct ip) + 2
|
||||
&& !memcmp(cp, old_rr, i)
|
||||
&& !(options & F_FLOOD)) {
|
||||
(void)printf("\t(same route)");
|
||||
i = ((i + 3) / 4) * 4;
|
||||
hlen -= i;
|
||||
cp += i;
|
||||
break;
|
||||
}
|
||||
old_rrlen = i;
|
||||
memmove(old_rr, cp, i);
|
||||
(void)printf("\nRR: ");
|
||||
for (;;) {
|
||||
l = *++cp;
|
||||
l = (l<<8) + *++cp;
|
||||
l = (l<<8) + *++cp;
|
||||
l = (l<<8) + *++cp;
|
||||
if (l == 0)
|
||||
(void)printf("\t0.0.0.0");
|
||||
else
|
||||
(void)printf("\t%s", pr_addr(ntohl(l)));
|
||||
hlen -= 4;
|
||||
i -= 4;
|
||||
if (i <= 0)
|
||||
break;
|
||||
(void)putchar('\n');
|
||||
}
|
||||
break;
|
||||
case IPOPT_NOP:
|
||||
(void)printf("\nNOP");
|
||||
break;
|
||||
default:
|
||||
(void)printf("\nunknown option %x", *cp);
|
||||
break;
|
||||
}
|
||||
if (!(options & F_FLOOD)) {
|
||||
(void)putchar('\n');
|
||||
(void)fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* in_cksum --
|
||||
* Checksum routine for Internet Protocol family headers (C Version)
|
||||
*/
|
||||
in_cksum(addr, len)
|
||||
u_short *addr;
|
||||
int len;
|
||||
{
|
||||
register int nleft = len;
|
||||
register u_short *w = addr;
|
||||
register int sum = 0;
|
||||
u_short answer = 0;
|
||||
|
||||
/*
|
||||
* Our algorithm is simple, using a 32 bit accumulator (sum), we add
|
||||
* sequential 16 bit words to it, and at the end, fold back all the
|
||||
* carry bits from the top 16 bits into the lower 16 bits.
|
||||
*/
|
||||
while (nleft > 1) {
|
||||
sum += *w++;
|
||||
nleft -= 2;
|
||||
}
|
||||
|
||||
/* mop up an odd byte, if necessary */
|
||||
if (nleft == 1) {
|
||||
*(u_char *)(&answer) = *(u_char *)w ;
|
||||
sum += answer;
|
||||
}
|
||||
|
||||
/* add back carry outs from top 16 bits to low 16 bits */
|
||||
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
|
||||
sum += (sum >> 16); /* add carry */
|
||||
answer = ~sum; /* truncate to 16 bits */
|
||||
return(answer);
|
||||
}
|
||||
|
||||
/*
|
||||
* tvsub --
|
||||
* Subtract 2 timeval structs: out = out - in. Out is assumed to
|
||||
* be >= in.
|
||||
*/
|
||||
tvsub(out, in)
|
||||
register struct timeval *out, *in;
|
||||
{
|
||||
if ((out->tv_usec -= in->tv_usec) < 0) {
|
||||
--out->tv_sec;
|
||||
out->tv_usec += 1000000;
|
||||
}
|
||||
out->tv_sec -= in->tv_sec;
|
||||
}
|
||||
|
||||
/*
|
||||
* finish --
|
||||
* Print out statistics, and give up.
|
||||
*/
|
||||
void
|
||||
finish()
|
||||
{
|
||||
register int i;
|
||||
|
||||
(void)signal(SIGINT, SIG_IGN);
|
||||
(void)putchar('\n');
|
||||
(void)fflush(stdout);
|
||||
(void)printf("--- %s ping statistics ---\n", hostname);
|
||||
(void)printf("%ld packets transmitted, ", ntransmitted);
|
||||
(void)printf("%ld packets received, ", nreceived);
|
||||
if (nrepeats)
|
||||
(void)printf("+%ld duplicates, ", nrepeats);
|
||||
if (ntransmitted)
|
||||
if (nreceived > ntransmitted)
|
||||
(void)printf("-- somebody's printing up packets!");
|
||||
else
|
||||
(void)printf("%d%% packet loss",
|
||||
(int) (((ntransmitted - nreceived) * 100) /
|
||||
ntransmitted));
|
||||
(void)putchar('\n');
|
||||
if (nreceived && timing) {
|
||||
/* Only display average to microseconds */
|
||||
i = 1000.0 * tsum / (nreceived + nrepeats);
|
||||
(void)printf("round-trip min/avg/max = %g/%g/%g ms\n",
|
||||
tmin, ((double)i) / 1000.0, tmax);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#ifdef notdef
|
||||
static char *ttab[] = {
|
||||
"Echo Reply", /* ip + seq + udata */
|
||||
"Dest Unreachable", /* net, host, proto, port, frag, sr + IP */
|
||||
"Source Quench", /* IP */
|
||||
"Redirect", /* redirect type, gateway, + IP */
|
||||
"Echo",
|
||||
"Time Exceeded", /* transit, frag reassem + IP */
|
||||
"Parameter Problem", /* pointer + IP */
|
||||
"Timestamp", /* id + seq + three timestamps */
|
||||
"Timestamp Reply", /* " */
|
||||
"Info Request", /* id + sq */
|
||||
"Info Reply" /* " */
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* pr_icmph --
|
||||
* Print a descriptive string about an ICMP header.
|
||||
*/
|
||||
pr_icmph(icp)
|
||||
struct icmp *icp;
|
||||
{
|
||||
switch(icp->icmp_type) {
|
||||
case ICMP_ECHOREPLY:
|
||||
(void)printf("Echo Reply\n");
|
||||
/* XXX ID + Seq + Data */
|
||||
break;
|
||||
case ICMP_UNREACH:
|
||||
switch(icp->icmp_code) {
|
||||
case ICMP_UNREACH_NET:
|
||||
(void)printf("Destination Net Unreachable\n");
|
||||
break;
|
||||
case ICMP_UNREACH_HOST:
|
||||
(void)printf("Destination Host Unreachable\n");
|
||||
break;
|
||||
case ICMP_UNREACH_PROTOCOL:
|
||||
(void)printf("Destination Protocol Unreachable\n");
|
||||
break;
|
||||
case ICMP_UNREACH_PORT:
|
||||
(void)printf("Destination Port Unreachable\n");
|
||||
break;
|
||||
case ICMP_UNREACH_NEEDFRAG:
|
||||
(void)printf("frag needed and DF set\n");
|
||||
break;
|
||||
case ICMP_UNREACH_SRCFAIL:
|
||||
(void)printf("Source Route Failed\n");
|
||||
break;
|
||||
default:
|
||||
(void)printf("Dest Unreachable, Bad Code: %d\n",
|
||||
icp->icmp_code);
|
||||
break;
|
||||
}
|
||||
/* Print returned IP header information */
|
||||
#ifndef icmp_data
|
||||
pr_retip(&icp->icmp_ip);
|
||||
#else
|
||||
pr_retip((struct ip *)icp->icmp_data);
|
||||
#endif
|
||||
break;
|
||||
case ICMP_SOURCEQUENCH:
|
||||
(void)printf("Source Quench\n");
|
||||
#ifndef icmp_data
|
||||
pr_retip(&icp->icmp_ip);
|
||||
#else
|
||||
pr_retip((struct ip *)icp->icmp_data);
|
||||
#endif
|
||||
break;
|
||||
case ICMP_REDIRECT:
|
||||
switch(icp->icmp_code) {
|
||||
case ICMP_REDIRECT_NET:
|
||||
(void)printf("Redirect Network");
|
||||
break;
|
||||
case ICMP_REDIRECT_HOST:
|
||||
(void)printf("Redirect Host");
|
||||
break;
|
||||
case ICMP_REDIRECT_TOSNET:
|
||||
(void)printf("Redirect Type of Service and Network");
|
||||
break;
|
||||
case ICMP_REDIRECT_TOSHOST:
|
||||
(void)printf("Redirect Type of Service and Host");
|
||||
break;
|
||||
default:
|
||||
(void)printf("Redirect, Bad Code: %d", icp->icmp_code);
|
||||
break;
|
||||
}
|
||||
(void)printf("(New addr: 0x%08lx)\n", icp->icmp_gwaddr.s_addr);
|
||||
#ifndef icmp_data
|
||||
pr_retip(&icp->icmp_ip);
|
||||
#else
|
||||
pr_retip((struct ip *)icp->icmp_data);
|
||||
#endif
|
||||
break;
|
||||
case ICMP_ECHO:
|
||||
(void)printf("Echo Request\n");
|
||||
/* XXX ID + Seq + Data */
|
||||
break;
|
||||
case ICMP_TIMXCEED:
|
||||
switch(icp->icmp_code) {
|
||||
case ICMP_TIMXCEED_INTRANS:
|
||||
(void)printf("Time to live exceeded\n");
|
||||
break;
|
||||
case ICMP_TIMXCEED_REASS:
|
||||
(void)printf("Frag reassembly time exceeded\n");
|
||||
break;
|
||||
default:
|
||||
(void)printf("Time exceeded, Bad Code: %d\n",
|
||||
icp->icmp_code);
|
||||
break;
|
||||
}
|
||||
#ifndef icmp_data
|
||||
pr_retip(&icp->icmp_ip);
|
||||
#else
|
||||
pr_retip((struct ip *)icp->icmp_data);
|
||||
#endif
|
||||
break;
|
||||
case ICMP_PARAMPROB:
|
||||
(void)printf("Parameter problem: pointer = 0x%02x\n",
|
||||
icp->icmp_hun.ih_pptr);
|
||||
#ifndef icmp_data
|
||||
pr_retip(&icp->icmp_ip);
|
||||
#else
|
||||
pr_retip((struct ip *)icp->icmp_data);
|
||||
#endif
|
||||
break;
|
||||
case ICMP_TSTAMP:
|
||||
(void)printf("Timestamp\n");
|
||||
/* XXX ID + Seq + 3 timestamps */
|
||||
break;
|
||||
case ICMP_TSTAMPREPLY:
|
||||
(void)printf("Timestamp Reply\n");
|
||||
/* XXX ID + Seq + 3 timestamps */
|
||||
break;
|
||||
case ICMP_IREQ:
|
||||
(void)printf("Information Request\n");
|
||||
/* XXX ID + Seq */
|
||||
break;
|
||||
case ICMP_IREQREPLY:
|
||||
(void)printf("Information Reply\n");
|
||||
/* XXX ID + Seq */
|
||||
break;
|
||||
#ifdef ICMP_MASKREQ
|
||||
case ICMP_MASKREQ:
|
||||
(void)printf("Address Mask Request\n");
|
||||
break;
|
||||
#endif
|
||||
#ifdef ICMP_MASKREPLY
|
||||
case ICMP_MASKREPLY:
|
||||
(void)printf("Address Mask Reply\n");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
(void)printf("Bad ICMP type: %d\n", icp->icmp_type);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* pr_iph --
|
||||
* Print an IP header with options.
|
||||
*/
|
||||
pr_iph(ip)
|
||||
struct ip *ip;
|
||||
{
|
||||
int hlen;
|
||||
u_char *cp;
|
||||
|
||||
hlen = ip->ip_hl << 2;
|
||||
cp = (u_char *)ip + 20; /* point to options */
|
||||
|
||||
(void)printf("Vr HL TOS Len ID Flg off TTL Pro cks Src Dst Data\n");
|
||||
(void)printf(" %1x %1x %02x %04x %04x",
|
||||
ip->ip_v, ip->ip_hl, ip->ip_tos, ip->ip_len, ip->ip_id);
|
||||
(void)printf(" %1x %04x", ((ip->ip_off) & 0xe000) >> 13,
|
||||
(ip->ip_off) & 0x1fff);
|
||||
(void)printf(" %02x %02x %04x", ip->ip_ttl, ip->ip_p, ip->ip_sum);
|
||||
(void)printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->ip_src.s_addr));
|
||||
(void)printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->ip_dst.s_addr));
|
||||
/* dump and option bytes */
|
||||
while (hlen-- > 20) {
|
||||
(void)printf("%02x", *cp++);
|
||||
}
|
||||
(void)putchar('\n');
|
||||
}
|
||||
|
||||
/*
|
||||
* pr_addr --
|
||||
* Return an ascii host address as a dotted quad and optionally with
|
||||
* a hostname.
|
||||
*/
|
||||
char *
|
||||
pr_addr(l)
|
||||
u_long l;
|
||||
{
|
||||
struct hostent *hp;
|
||||
static char buf[80];
|
||||
|
||||
if ((options & F_NUMERIC) ||
|
||||
!(hp = gethostbyaddr((char *)&l, 4, AF_INET)))
|
||||
(void)sprintf(buf, "%s", inet_ntoa(*(struct in_addr *)&l));
|
||||
else
|
||||
(void)sprintf(buf, "%s (%s)", hp->h_name,
|
||||
inet_ntoa(*(struct in_addr *)&l));
|
||||
return(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* pr_retip --
|
||||
* Dump some info on a returned (via ICMP) IP packet.
|
||||
*/
|
||||
pr_retip(ip)
|
||||
struct ip *ip;
|
||||
{
|
||||
int hlen;
|
||||
u_char *cp;
|
||||
|
||||
pr_iph(ip);
|
||||
hlen = ip->ip_hl << 2;
|
||||
cp = (u_char *)ip + hlen;
|
||||
|
||||
if (ip->ip_p == 6)
|
||||
(void)printf("TCP: from port %u, to port %u (decimal)\n",
|
||||
(*cp * 256 + *(cp + 1)), (*(cp + 2) * 256 + *(cp + 3)));
|
||||
else if (ip->ip_p == 17)
|
||||
(void)printf("UDP: from port %u, to port %u (decimal)\n",
|
||||
(*cp * 256 + *(cp + 1)), (*(cp + 2) * 256 + *(cp + 3)));
|
||||
}
|
||||
|
||||
fill(bp, patp)
|
||||
char *bp, *patp;
|
||||
{
|
||||
register int ii, jj, kk;
|
||||
int pat[16];
|
||||
char *cp;
|
||||
|
||||
for (cp = patp; *cp; cp++)
|
||||
if (!isxdigit(*cp)) {
|
||||
(void)fprintf(stderr,
|
||||
"ping: patterns must be specified as hex digits.\n");
|
||||
exit(1);
|
||||
}
|
||||
ii = sscanf(patp,
|
||||
"%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
|
||||
&pat[0], &pat[1], &pat[2], &pat[3], &pat[4], &pat[5], &pat[6],
|
||||
&pat[7], &pat[8], &pat[9], &pat[10], &pat[11], &pat[12],
|
||||
&pat[13], &pat[14], &pat[15]);
|
||||
|
||||
if (ii > 0)
|
||||
for (kk = 0;
|
||||
kk <= MAXPACKET - (8 + sizeof(struct timeval) + ii);
|
||||
kk += ii)
|
||||
for (jj = 0; jj < ii; ++jj)
|
||||
bp[jj + kk] = pat[jj];
|
||||
if (!(options & F_QUIET)) {
|
||||
(void)printf("PATTERN: 0x");
|
||||
for (jj = 0; jj < ii; ++jj)
|
||||
(void)printf("%02x", bp[jj] & 0xFF);
|
||||
(void)printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"usage: ping [-Rdfnqrv] [-c count] [-i wait] [-l preload]\n\t[-p pattern] [-s packetsize] host\n");
|
||||
exit(1);
|
||||
}
|
175
sbin/route/ccitt_addr.c
Normal file
175
sbin/route/ccitt_addr.c
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. 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.
|
||||
*
|
||||
* @(#)ccitt_addr.c 8.2 (Berkeley) 4/28/95
|
||||
*/
|
||||
/*
|
||||
* parse CCITT addresses
|
||||
*
|
||||
* Addresses must have the format: [hpr],x121address[,userdata][,protocol]
|
||||
* items enclosed with square brackets are optional
|
||||
* 'h' or 'p' means hi priority (packet size = 128; specific to Datapac
|
||||
* and necessary only for X.25(76) and non-negotiating X.25(80) DTE's)
|
||||
* 'r' means reverse charge (remote DTE pays for call).
|
||||
* The x121address consists of an optional netid and dot, followed
|
||||
* by a dte address.
|
||||
*
|
||||
* Frank Pronk
|
||||
* The University of British Columbia
|
||||
* Laboratory for Computational Vision
|
||||
* Copyright (c) 1984
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netccitt/x25.h>
|
||||
|
||||
static char *copychar ();
|
||||
|
||||
ccitt_addr (addr, xp)
|
||||
char *addr;
|
||||
register struct sockaddr_x25 *xp;
|
||||
{
|
||||
register char *p, *ap, *limit;
|
||||
int havenet = 0;
|
||||
|
||||
memset(xp, 0, sizeof (*xp));
|
||||
xp->x25_family = AF_CCITT;
|
||||
xp->x25_len = sizeof(*xp);
|
||||
p = addr;
|
||||
|
||||
/*
|
||||
* process optional priority and reverse charging flags
|
||||
*/
|
||||
|
||||
if (*p == 'p' || *p == 'r' || *p == 'h') {
|
||||
while (*p == 'p' || *p == 'r' || *p == 'h') {
|
||||
if (*p == 'p' || *p == 'h')
|
||||
xp->x25_opts.op_psize = X25_PS128;
|
||||
else if (*p == 'r')
|
||||
xp->x25_opts.op_flags |= X25_REVERSE_CHARGE;
|
||||
p++;
|
||||
}
|
||||
if (*p != ',')
|
||||
return (0);
|
||||
p++;
|
||||
}
|
||||
if (*p == '\0')
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* [network id:]X.121 address
|
||||
*/
|
||||
|
||||
ap = xp->x25_addr;
|
||||
limit = ap + sizeof (xp->x25_addr) - 1;
|
||||
while (*p) {
|
||||
if (*p == ',')
|
||||
break;
|
||||
if (*p == '.' || *p == ':') {
|
||||
if (havenet)
|
||||
return (0);
|
||||
havenet++;
|
||||
xp->x25_net = atoi (xp->x25_addr);
|
||||
p++;
|
||||
ap = xp->x25_addr;
|
||||
*ap = '\0';
|
||||
}
|
||||
if (*p < '0' || *p > '9')
|
||||
return (0);
|
||||
if (ap >= limit)
|
||||
return (0);
|
||||
*ap++ = *p++;
|
||||
}
|
||||
if (*p == '\0')
|
||||
return (1);
|
||||
|
||||
/*
|
||||
* optional user data, bytes 4 to 16
|
||||
*/
|
||||
|
||||
p++;
|
||||
ap = xp->x25_udata + 4; /* first four bytes are protocol id */
|
||||
limit = ap + sizeof (xp->x25_udata) - 4;
|
||||
xp->x25_udlen = 4;
|
||||
while (*p) {
|
||||
if (*p == ',')
|
||||
break;
|
||||
if (ap >= limit)
|
||||
return (0);
|
||||
p = copychar (p, ap++);
|
||||
xp->x25_udlen++;
|
||||
}
|
||||
if (xp->x25_udlen == 4)
|
||||
xp->x25_udlen = 0;
|
||||
if (*p == '\0')
|
||||
return (1);
|
||||
|
||||
p++;
|
||||
ap = xp->x25_udata; /* protocol id */
|
||||
limit = ap + (xp->x25_udlen ? 4 : sizeof(xp->x25_udata));
|
||||
while (*p) {
|
||||
if (*p == ',')
|
||||
return (0);
|
||||
if (ap >= limit)
|
||||
return (0);
|
||||
p = copychar (p, ap++);
|
||||
}
|
||||
if (xp->x25_udlen == 0)
|
||||
xp->x25_udlen = ap - xp->x25_udata;
|
||||
return (1);
|
||||
}
|
||||
|
||||
static char *
|
||||
copychar (from, to)
|
||||
register char *from, *to;
|
||||
{
|
||||
register int n;
|
||||
|
||||
if (*from != '\\' || from[1] < '0' || from[1] > '7') {
|
||||
*to = *from++;
|
||||
return (from);
|
||||
}
|
||||
n = *++from - '0';
|
||||
from++;
|
||||
if (*from >= '0' && *from <= '7') {
|
||||
register int n1;
|
||||
|
||||
n = n*8 + *from++ - '0';
|
||||
if (*from >= '0' && *from <= '7' && (n1 = n*8 + *from-'0') < 256) {
|
||||
n = n1;
|
||||
from++;
|
||||
}
|
||||
}
|
||||
*to = n;
|
||||
return (from);
|
||||
}
|
325
sbin/route/route.8
Normal file
325
sbin/route/route.8
Normal file
@ -0,0 +1,325 @@
|
||||
.\" 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. 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.
|
||||
.\"
|
||||
.\" @(#)route.8 8.4 (Berkeley) 6/1/94
|
||||
.\"
|
||||
.Dd June 1, 1994
|
||||
.Dt ROUTE 8
|
||||
.Os BSD 4.4
|
||||
.Sh NAME
|
||||
.Nm route
|
||||
.Nd manually manipulate the routing tables.
|
||||
.Sh SYNOPSIS
|
||||
.Nm route
|
||||
.Op Fl nqv
|
||||
.Ar command
|
||||
.Oo
|
||||
.Op Ar modifiers
|
||||
.Ar args
|
||||
.Oc
|
||||
.Sh DESCRIPTION
|
||||
.Nm Route
|
||||
is a utility used to manually manipulate the network
|
||||
routing tables. It normally is not needed, as a
|
||||
system routing table management daemon such as
|
||||
.Xr routed 8 ,
|
||||
should tend to this task.
|
||||
.Pp
|
||||
The
|
||||
.Nm route :
|
||||
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 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 v
|
||||
(verbose) Print additional details.
|
||||
.It Fl q
|
||||
Suppress all output.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Nm route :
|
||||
utility provides six commands:
|
||||
.Pp
|
||||
.Bl -tag -width Fl -compact
|
||||
.It Cm add
|
||||
Add a route.
|
||||
.It Cm flush
|
||||
Remove all routes.
|
||||
.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 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 route Op Fl n
|
||||
.Cm monitor
|
||||
.Ed
|
||||
.Pp
|
||||
The flush command has the syntax
|
||||
.Pp
|
||||
.Bd -filled -offset indent -compact
|
||||
.Nm route Op Fl n
|
||||
.Cm flush
|
||||
.Op Ar family
|
||||
.Ed
|
||||
.Pp
|
||||
If the
|
||||
.Cm flush
|
||||
command is specified,
|
||||
.Nm route
|
||||
will ``flush'' the routing tables of all gateway entries.
|
||||
When the address family may is specified by any of the
|
||||
.Fl osi ,
|
||||
.Fl xns ,
|
||||
or
|
||||
.Fl inet
|
||||
modifiers, only routes having destinations with addresses in the
|
||||
delineated family will be deleted.
|
||||
.Pp
|
||||
The other commands have the following syntax:
|
||||
.Pp
|
||||
.Bd -filled -offset indent -compact
|
||||
.Nm route 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,
|
||||
.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
|
||||
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.
|
||||
.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
|
||||
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 osi ,
|
||||
and
|
||||
.Fl link
|
||||
specify that all subsequent addresses are in the
|
||||
.Tn XNS
|
||||
.Tn OSI
|
||||
address families,
|
||||
or are specified as link-level addresses,
|
||||
and the names must be numeric specifications rather than
|
||||
symbolic names.
|
||||
.Pp
|
||||
The optional
|
||||
.Fl netmask
|
||||
qualifier is intended
|
||||
to achieve the effect of an
|
||||
.Tn OSI
|
||||
.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 AF_INET case
|
||||
can be overridden by making sure this option follows the destination parameter.
|
||||
.Pp
|
||||
Routes have associated flags which influence operation of the protocols
|
||||
when sending to destinations matched by the routes.
|
||||
These flags may be set (or sometimes cleared)
|
||||
by indicating the following corresponding modifiers:
|
||||
.Bd -literal
|
||||
-cloning RTF_CLONING - generates a new route on use
|
||||
-xresolve RTF_XRESOLVE - emit mesg on use (for external lookup)
|
||||
-iface ~RTF_GATEWAY - destination is directly reachable
|
||||
-static RTF_STATIC - manually added route
|
||||
-nostatic ~RTF_STATIC - pretend route added by kernel or daemon
|
||||
-reject RTF_REJECT - emit an ICMP unreachable when matched
|
||||
-blackhole RTF_BLACKHOLE - silently discard pkts (during updates)
|
||||
-proto1 RTF_PROTO1 - set protocol specific routing flag #1
|
||||
-proto2 RTF_PROTO2 - set protocol specific routing flag #2
|
||||
-llinfo RTF_LLINFO - validly translates proto addr to link addr
|
||||
.Ed
|
||||
.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 (as in the
|
||||
.Tn ISO
|
||||
case where several interfaces may have the
|
||||
same address), 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 Route
|
||||
uses a routing socket and the new message types
|
||||
RTM_ADD,
|
||||
RTM_DELETE,
|
||||
RTM_GET,
|
||||
and
|
||||
RTM_CHANGE.
|
||||
As such, only the super-user may modify
|
||||
the routing tables.
|
||||
.ne 1i
|
||||
.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.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr netintro 4 ,
|
||||
.Xr route 4 ,
|
||||
.Xr esis 4 ,
|
||||
.Xr routed 8 ,
|
||||
.Xr XNSrouted 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command appeared in
|
||||
.Bx 4.2 .
|
||||
.Sh BUGS
|
||||
The first paragraph may have slightly exaggerated
|
||||
.Xr routed Ns 's
|
||||
abilities.
|
1415
sbin/route/route.c
Normal file
1415
sbin/route/route.c
Normal file
File diff suppressed because it is too large
Load Diff
649
sbin/savecore/savecore.c
Normal file
649
sbin/savecore/savecore.c
Normal file
@ -0,0 +1,649 @@
|
||||
/*-
|
||||
* Copyright (c) 1986, 1992, 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. 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1986, 1992, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)savecore.c 8.5 (Berkeley) 4/28/95";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <nlist.h>
|
||||
#include <paths.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <tzfile.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define ok(number) ((number) - KERNBASE)
|
||||
|
||||
struct nlist current_nl[] = { /* Namelist for currently running system. */
|
||||
#define X_DUMPDEV 0
|
||||
{ "_dumpdev" },
|
||||
#define X_DUMPLO 1
|
||||
{ "_dumplo" },
|
||||
#define X_TIME 2
|
||||
{ "_time" },
|
||||
#define X_DUMPSIZE 3
|
||||
{ "_dumpsize" },
|
||||
#define X_VERSION 4
|
||||
{ "_version" },
|
||||
#define X_PANICSTR 5
|
||||
{ "_panicstr" },
|
||||
#define X_DUMPMAG 6
|
||||
{ "_dumpmag" },
|
||||
{ "" },
|
||||
};
|
||||
int cursyms[] = { X_DUMPDEV, X_DUMPLO, X_VERSION, X_DUMPMAG, -1 };
|
||||
int dumpsyms[] = { X_TIME, X_DUMPSIZE, X_VERSION, X_PANICSTR, X_DUMPMAG, -1 };
|
||||
|
||||
struct nlist dump_nl[] = { /* Name list for dumped system. */
|
||||
{ "_dumpdev" }, /* Entries MUST be the same as */
|
||||
{ "_dumplo" }, /* those in current_nl[]. */
|
||||
{ "_time" },
|
||||
{ "_dumpsize" },
|
||||
{ "_version" },
|
||||
{ "_panicstr" },
|
||||
{ "_dumpmag" },
|
||||
{ "" },
|
||||
};
|
||||
|
||||
/* Types match kernel declarations. */
|
||||
long dumplo; /* where dump starts on dumpdev */
|
||||
int dumpmag; /* magic number in dump */
|
||||
int dumpsize; /* amount of memory dumped */
|
||||
|
||||
char *vmunix;
|
||||
char *dirname; /* directory to save dumps in */
|
||||
char *ddname; /* name of dump device */
|
||||
dev_t dumpdev; /* dump device */
|
||||
int dumpfd; /* read/write descriptor on block dev */
|
||||
time_t now; /* current date */
|
||||
char panic_mesg[1024];
|
||||
int panicstr;
|
||||
char vers[1024];
|
||||
|
||||
int clear, compress, force, verbose; /* flags */
|
||||
|
||||
void check_kmem __P((void));
|
||||
int check_space __P((void));
|
||||
void clear_dump __P((void));
|
||||
int Create __P((char *, int));
|
||||
int dump_exists __P((void));
|
||||
char *find_dev __P((dev_t, int));
|
||||
int get_crashtime __P((void));
|
||||
void kmem_setup __P((void));
|
||||
void log __P((int, char *, ...));
|
||||
void Lseek __P((int, off_t, int));
|
||||
int Open __P((char *, int rw));
|
||||
int Read __P((int, void *, int));
|
||||
char *rawname __P((char *s));
|
||||
void save_core __P((void));
|
||||
void usage __P((void));
|
||||
void Write __P((int, void *, int));
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int ch;
|
||||
|
||||
openlog("savecore", LOG_PERROR, LOG_DAEMON);
|
||||
|
||||
while ((ch = getopt(argc, argv, "cdfN:vz")) != EOF)
|
||||
switch(ch) {
|
||||
case 'c':
|
||||
clear = 1;
|
||||
break;
|
||||
case 'd': /* Not documented. */
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
case 'f':
|
||||
force = 1;
|
||||
break;
|
||||
case 'N':
|
||||
vmunix = optarg;
|
||||
break;
|
||||
case 'z':
|
||||
compress = 1;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (!clear) {
|
||||
if (argc != 1 && argc != 2)
|
||||
usage();
|
||||
dirname = argv[0];
|
||||
}
|
||||
if (argc == 2)
|
||||
vmunix = argv[1];
|
||||
|
||||
(void)time(&now);
|
||||
kmem_setup();
|
||||
|
||||
if (clear) {
|
||||
clear_dump();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (!dump_exists() && !force)
|
||||
exit(1);
|
||||
|
||||
check_kmem();
|
||||
|
||||
if (panicstr)
|
||||
syslog(LOG_ALERT, "reboot after panic: %s", panic_mesg);
|
||||
else
|
||||
syslog(LOG_ALERT, "reboot");
|
||||
|
||||
if ((!get_crashtime() || !check_space()) && !force)
|
||||
exit(1);
|
||||
|
||||
save_core();
|
||||
|
||||
clear_dump();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
kmem_setup()
|
||||
{
|
||||
FILE *fp;
|
||||
int kmem, i;
|
||||
char *dump_sys;
|
||||
|
||||
/*
|
||||
* Some names we need for the currently running system, others for
|
||||
* the system that was running when the dump was made. The values
|
||||
* obtained from the current system are used to look for things in
|
||||
* /dev/kmem that cannot be found in the dump_sys namelist, but are
|
||||
* presumed to be the same (since the disk partitions are probably
|
||||
* the same!)
|
||||
*/
|
||||
if ((nlist(_PATH_UNIX, current_nl)) == -1)
|
||||
syslog(LOG_ERR, "%s: nlist: %s", _PATH_UNIX, strerror(errno));
|
||||
for (i = 0; cursyms[i] != -1; i++)
|
||||
if (current_nl[cursyms[i]].n_value == 0) {
|
||||
syslog(LOG_ERR, "%s: %s not in namelist",
|
||||
_PATH_UNIX, current_nl[cursyms[i]].n_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
dump_sys = vmunix ? vmunix : _PATH_UNIX;
|
||||
if ((nlist(dump_sys, dump_nl)) == -1)
|
||||
syslog(LOG_ERR, "%s: nlist: %s", dump_sys, strerror(errno));
|
||||
for (i = 0; dumpsyms[i] != -1; i++)
|
||||
if (dump_nl[dumpsyms[i]].n_value == 0) {
|
||||
syslog(LOG_ERR, "%s: %s not in namelist",
|
||||
dump_sys, dump_nl[dumpsyms[i]].n_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
kmem = Open(_PATH_KMEM, O_RDONLY);
|
||||
Lseek(kmem, (off_t)current_nl[X_DUMPDEV].n_value, L_SET);
|
||||
(void)Read(kmem, &dumpdev, sizeof(dumpdev));
|
||||
if (dumpdev == NODEV) {
|
||||
syslog(LOG_WARNING, "no core dump (no dumpdev)");
|
||||
exit(1);
|
||||
}
|
||||
Lseek(kmem, (off_t)current_nl[X_DUMPLO].n_value, L_SET);
|
||||
(void)Read(kmem, &dumplo, sizeof(dumplo));
|
||||
if (verbose)
|
||||
(void)printf("dumplo = %d (%d * %d)\n",
|
||||
dumplo, dumplo/DEV_BSIZE, DEV_BSIZE);
|
||||
Lseek(kmem, (off_t)current_nl[X_DUMPMAG].n_value, L_SET);
|
||||
(void)Read(kmem, &dumpmag, sizeof(dumpmag));
|
||||
dumplo *= DEV_BSIZE;
|
||||
ddname = find_dev(dumpdev, S_IFBLK);
|
||||
dumpfd = Open(ddname, O_RDWR);
|
||||
fp = fdopen(kmem, "r");
|
||||
if (fp == NULL) {
|
||||
syslog(LOG_ERR, "%s: fdopen: %m", _PATH_KMEM);
|
||||
exit(1);
|
||||
}
|
||||
if (vmunix)
|
||||
return;
|
||||
(void)fseek(fp, (off_t)current_nl[X_VERSION].n_value, L_SET);
|
||||
(void)fgets(vers, sizeof(vers), fp);
|
||||
|
||||
/* Don't fclose(fp), we use dumpfd later. */
|
||||
}
|
||||
|
||||
void
|
||||
check_kmem()
|
||||
{
|
||||
register char *cp;
|
||||
FILE *fp;
|
||||
char core_vers[1024];
|
||||
|
||||
fp = fdopen(dumpfd, "r");
|
||||
if (fp == NULL) {
|
||||
syslog(LOG_ERR, "%s: fdopen: %m", ddname);
|
||||
exit(1);
|
||||
}
|
||||
fseek(fp, (off_t)(dumplo + ok(dump_nl[X_VERSION].n_value)), L_SET);
|
||||
fgets(core_vers, sizeof(core_vers), fp);
|
||||
if (strcmp(vers, core_vers) && vmunix == 0)
|
||||
syslog(LOG_WARNING,
|
||||
"warning: %s version mismatch:\n\t%s\nand\t%s\n",
|
||||
_PATH_UNIX, vers, core_vers);
|
||||
(void)fseek(fp,
|
||||
(off_t)(dumplo + ok(dump_nl[X_PANICSTR].n_value)), L_SET);
|
||||
(void)fread(&panicstr, sizeof(panicstr), 1, fp);
|
||||
if (panicstr) {
|
||||
(void)fseek(fp, dumplo + ok(panicstr), L_SET);
|
||||
cp = panic_mesg;
|
||||
do
|
||||
*cp = getc(fp);
|
||||
while (*cp++ && cp < &panic_mesg[sizeof(panic_mesg)]);
|
||||
}
|
||||
/* Don't fclose(fp), we use dumpfd later. */
|
||||
}
|
||||
|
||||
void
|
||||
clear_dump()
|
||||
{
|
||||
long newdumplo;
|
||||
|
||||
newdumplo = 0;
|
||||
Lseek(dumpfd, (off_t)(dumplo + ok(dump_nl[X_DUMPMAG].n_value)), L_SET);
|
||||
Write(dumpfd, &newdumplo, sizeof(newdumplo));
|
||||
}
|
||||
|
||||
int
|
||||
dump_exists()
|
||||
{
|
||||
int newdumpmag;
|
||||
|
||||
Lseek(dumpfd, (off_t)(dumplo + ok(dump_nl[X_DUMPMAG].n_value)), L_SET);
|
||||
(void)Read(dumpfd, &newdumpmag, sizeof(newdumpmag));
|
||||
if (newdumpmag != dumpmag) {
|
||||
if (verbose)
|
||||
syslog(LOG_WARNING, "magic number mismatch (%x != %x)",
|
||||
newdumpmag, dumpmag);
|
||||
syslog(LOG_WARNING, "no core dump");
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
char buf[1024 * 1024];
|
||||
|
||||
void
|
||||
save_core()
|
||||
{
|
||||
register FILE *fp;
|
||||
register int bounds, ifd, nr, nw, ofd;
|
||||
char *rawp, path[MAXPATHLEN];
|
||||
|
||||
/*
|
||||
* Get the current number and update the bounds file. Do the update
|
||||
* now, because may fail later and don't want to overwrite anything.
|
||||
*/
|
||||
(void)snprintf(path, sizeof(path), "%s/bounds", dirname);
|
||||
if ((fp = fopen(path, "r")) == NULL)
|
||||
goto err1;
|
||||
if (fgets(buf, sizeof(buf), fp) == NULL) {
|
||||
if (ferror(fp))
|
||||
err1: syslog(LOG_WARNING, "%s: %s", path, strerror(errno));
|
||||
bounds = 0;
|
||||
} else
|
||||
bounds = atoi(buf);
|
||||
if (fp != NULL)
|
||||
(void)fclose(fp);
|
||||
if ((fp = fopen(path, "w")) == NULL)
|
||||
syslog(LOG_ERR, "%s: %m", path);
|
||||
else {
|
||||
(void)fprintf(fp, "%d\n", bounds + 1);
|
||||
(void)fclose(fp);
|
||||
}
|
||||
(void)fclose(fp);
|
||||
|
||||
/* Create the core file. */
|
||||
(void)snprintf(path, sizeof(path), "%s/vmcore.%d%s",
|
||||
dirname, bounds, compress ? ".Z" : "");
|
||||
if (compress) {
|
||||
if ((fp = zopen(path, "w", 0)) == NULL) {
|
||||
syslog(LOG_ERR, "%s: %s", path, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
} else
|
||||
ofd = Create(path, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
|
||||
/* Open the raw device. */
|
||||
rawp = rawname(ddname);
|
||||
if ((ifd = open(rawp, O_RDONLY)) == -1) {
|
||||
syslog(LOG_WARNING, "%s: %m; using block device", rawp);
|
||||
ifd = dumpfd;
|
||||
}
|
||||
|
||||
/* Read the dump size. */
|
||||
Lseek(dumpfd, (off_t)(dumplo + ok(dump_nl[X_DUMPSIZE].n_value)), L_SET);
|
||||
(void)Read(dumpfd, &dumpsize, sizeof(dumpsize));
|
||||
|
||||
/* Seek to the start of the core. */
|
||||
Lseek(ifd, (off_t)dumplo, L_SET);
|
||||
|
||||
/* Copy the core file. */
|
||||
dumpsize *= NBPG;
|
||||
syslog(LOG_NOTICE, "writing %score to %s",
|
||||
compress ? "compressed " : "", path);
|
||||
for (; dumpsize > 0; dumpsize -= nr) {
|
||||
(void)printf("%6dK\r", dumpsize / 1024);
|
||||
(void)fflush(stdout);
|
||||
nr = read(ifd, buf, MIN(dumpsize, sizeof(buf)));
|
||||
if (nr <= 0) {
|
||||
if (nr == 0)
|
||||
syslog(LOG_WARNING,
|
||||
"WARNING: EOF on dump device");
|
||||
else
|
||||
syslog(LOG_ERR, "%s: %m", rawp);
|
||||
goto err2;
|
||||
}
|
||||
if (compress)
|
||||
nw = fwrite(buf, 1, nr, fp);
|
||||
else
|
||||
nw = write(ofd, buf, nr);
|
||||
if (nw != nr) {
|
||||
syslog(LOG_ERR, "%s: %s",
|
||||
path, strerror(nw == 0 ? EIO : errno));
|
||||
err2: syslog(LOG_WARNING,
|
||||
"WARNING: vmcore may be incomplete");
|
||||
(void)printf("\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
(void)printf("\n");
|
||||
(void)close(ifd);
|
||||
if (compress)
|
||||
(void)fclose(fp);
|
||||
else
|
||||
(void)close(ofd);
|
||||
|
||||
/* Copy the kernel. */
|
||||
ifd = Open(vmunix ? vmunix : _PATH_UNIX, O_RDONLY);
|
||||
(void)snprintf(path, sizeof(path), "%s/vmunix.%d%s",
|
||||
dirname, bounds, compress ? ".Z" : "");
|
||||
if (compress) {
|
||||
if ((fp = zopen(path, "w", 0)) == NULL) {
|
||||
syslog(LOG_ERR, "%s: %s", path, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
} else
|
||||
ofd = Create(path, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
syslog(LOG_NOTICE, "writing %skernel to %s",
|
||||
compress ? "compressed " : "", path);
|
||||
while ((nr = read(ifd, buf, sizeof(buf))) > 0) {
|
||||
if (compress)
|
||||
nw = fwrite(buf, 1, nr, fp);
|
||||
else
|
||||
nw = write(ofd, buf, nr);
|
||||
if (nw != nr) {
|
||||
syslog(LOG_ERR, "%s: %s",
|
||||
path, strerror(nw == 0 ? EIO : errno));
|
||||
syslog(LOG_WARNING,
|
||||
"WARNING: vmunix may be incomplete");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (nr < 0) {
|
||||
syslog(LOG_ERR, "%s: %s",
|
||||
vmunix ? vmunix : _PATH_UNIX, strerror(errno));
|
||||
syslog(LOG_WARNING,
|
||||
"WARNING: vmunix may be incomplete");
|
||||
exit(1);
|
||||
}
|
||||
if (compress)
|
||||
(void)fclose(fp);
|
||||
else
|
||||
(void)close(ofd);
|
||||
}
|
||||
|
||||
char *
|
||||
find_dev(dev, type)
|
||||
register dev_t dev;
|
||||
register int type;
|
||||
{
|
||||
register DIR *dfd;
|
||||
struct dirent *dir;
|
||||
struct stat sb;
|
||||
char *dp, devname[MAXPATHLEN + 1];
|
||||
|
||||
if ((dfd = opendir(_PATH_DEV)) == NULL) {
|
||||
syslog(LOG_ERR, "%s: %s", _PATH_DEV, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
(void)strcpy(devname, _PATH_DEV);
|
||||
while ((dir = readdir(dfd))) {
|
||||
(void)strcpy(devname + sizeof(_PATH_DEV) - 1, dir->d_name);
|
||||
if (lstat(devname, &sb)) {
|
||||
syslog(LOG_ERR, "%s: %s", devname, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
if ((sb.st_mode & S_IFMT) != type)
|
||||
continue;
|
||||
if (dev == sb.st_rdev) {
|
||||
closedir(dfd);
|
||||
if ((dp = strdup(devname)) == NULL) {
|
||||
syslog(LOG_ERR, "%s", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
return (dp);
|
||||
}
|
||||
}
|
||||
closedir(dfd);
|
||||
syslog(LOG_ERR, "can't find device %d/%d", major(dev), minor(dev));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char *
|
||||
rawname(s)
|
||||
char *s;
|
||||
{
|
||||
char *sl, name[MAXPATHLEN];
|
||||
|
||||
if ((sl = strrchr(s, '/')) == NULL || sl[1] == '0') {
|
||||
syslog(LOG_ERR,
|
||||
"can't make raw dump device name from %s", s);
|
||||
return (s);
|
||||
}
|
||||
(void)snprintf(name, sizeof(name), "%.*s/r%s", sl - s, s, sl + 1);
|
||||
if ((sl = strdup(name)) == NULL) {
|
||||
syslog(LOG_ERR, "%s", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
return (sl);
|
||||
}
|
||||
|
||||
int
|
||||
get_crashtime()
|
||||
{
|
||||
time_t dumptime; /* Time the dump was taken. */
|
||||
|
||||
Lseek(dumpfd, (off_t)(dumplo + ok(dump_nl[X_TIME].n_value)), L_SET);
|
||||
(void)Read(dumpfd, &dumptime, sizeof(dumptime));
|
||||
if (dumptime == 0) {
|
||||
if (verbose)
|
||||
syslog(LOG_ERR, "dump time is zero");
|
||||
return (0);
|
||||
}
|
||||
(void)printf("savecore: system went down at %s", ctime(&dumptime));
|
||||
#define LEEWAY (7 * SECSPERDAY)
|
||||
if (dumptime < now - LEEWAY || dumptime > now + LEEWAY) {
|
||||
(void)printf("dump time is unreasonable\n");
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
check_space()
|
||||
{
|
||||
register FILE *fp;
|
||||
char *tvmunix;
|
||||
off_t minfree, spacefree, vmunixsize, needed;
|
||||
struct stat st;
|
||||
struct statfs fsbuf;
|
||||
char buf[100], path[MAXPATHLEN];
|
||||
|
||||
tvmunix = vmunix ? vmunix : _PATH_UNIX;
|
||||
if (stat(tvmunix, &st) < 0) {
|
||||
syslog(LOG_ERR, "%s: %m", tvmunix);
|
||||
exit(1);
|
||||
}
|
||||
vmunixsize = st.st_blocks * S_BLKSIZE;
|
||||
if (statfs(dirname, &fsbuf) < 0) {
|
||||
syslog(LOG_ERR, "%s: %m", dirname);
|
||||
exit(1);
|
||||
}
|
||||
spacefree = (fsbuf.f_bavail * fsbuf.f_bsize) / 1024;
|
||||
|
||||
(void)snprintf(path, sizeof(path), "%s/minfree", dirname);
|
||||
if ((fp = fopen(path, "r")) == NULL)
|
||||
minfree = 0;
|
||||
else {
|
||||
if (fgets(buf, sizeof(buf), fp) == NULL)
|
||||
minfree = 0;
|
||||
else
|
||||
minfree = atoi(buf);
|
||||
(void)fclose(fp);
|
||||
}
|
||||
|
||||
needed = (dumpsize + vmunixsize) / 1024;
|
||||
if (minfree > 0 && spacefree - needed < minfree) {
|
||||
syslog(LOG_WARNING,
|
||||
"no dump, not enough free space on device");
|
||||
return (0);
|
||||
}
|
||||
if (spacefree - needed < minfree)
|
||||
syslog(LOG_WARNING,
|
||||
"dump performed, but free space threshold crossed");
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
Open(name, rw)
|
||||
char *name;
|
||||
int rw;
|
||||
{
|
||||
int fd;
|
||||
|
||||
if ((fd = open(name, rw, 0)) < 0) {
|
||||
syslog(LOG_ERR, "%s: %m", name);
|
||||
exit(1);
|
||||
}
|
||||
return (fd);
|
||||
}
|
||||
|
||||
int
|
||||
Read(fd, bp, size)
|
||||
int fd, size;
|
||||
void *bp;
|
||||
{
|
||||
int nr;
|
||||
|
||||
nr = read(fd, bp, size);
|
||||
if (nr != size) {
|
||||
syslog(LOG_ERR, "read: %m");
|
||||
exit(1);
|
||||
}
|
||||
return (nr);
|
||||
}
|
||||
|
||||
void
|
||||
Lseek(fd, off, flag)
|
||||
int fd, flag;
|
||||
off_t off;
|
||||
{
|
||||
off_t ret;
|
||||
|
||||
ret = lseek(fd, off, flag);
|
||||
if (ret == -1) {
|
||||
syslog(LOG_ERR, "lseek: %m");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
Create(file, mode)
|
||||
char *file;
|
||||
int mode;
|
||||
{
|
||||
register int fd;
|
||||
|
||||
fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, mode);
|
||||
if (fd < 0) {
|
||||
syslog(LOG_ERR, "%s: %m", file);
|
||||
exit(1);
|
||||
}
|
||||
return (fd);
|
||||
}
|
||||
|
||||
void
|
||||
Write(fd, bp, size)
|
||||
int fd, size;
|
||||
void *bp;
|
||||
{
|
||||
int n;
|
||||
|
||||
if ((n = write(fd, bp, size)) < size) {
|
||||
syslog(LOG_ERR, "write: %s", strerror(n == -1 ? errno : EIO));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
usage()
|
||||
{
|
||||
(void)syslog(LOG_ERR, "usage: savecore [-cfvz] [-N system] directory");
|
||||
exit(1);
|
||||
}
|
664
sbin/scsiformat/scsiformat.c
Normal file
664
sbin/scsiformat/scsiformat.c
Normal file
@ -0,0 +1,664 @@
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @(#)scsiformat.c 5.5 (Berkeley) 4/2/94
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
char copyright[] =
|
||||
"@(#) Copyright (c) 1992, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)scsiformat.c 5.5 (Berkeley) 4/2/94";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <dev/scsi/scsi.h>
|
||||
#include <dev/scsi/disk.h>
|
||||
#include <dev/scsi/disktape.h>
|
||||
#include <dev/scsi/scsi_ioctl.h>
|
||||
|
||||
#define COMPAT_HPSCSI
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int fd;
|
||||
char *device;
|
||||
|
||||
void scsi_str __P((char *, char *, int));
|
||||
void do_command __P((int, struct scsi_cdb *, void *, int));
|
||||
void do_format __P((void));
|
||||
void print_capacity __P((void));
|
||||
void print_inquiry __P((void));
|
||||
void prflags __P((int, const char *));
|
||||
u_char *print_mode_page __P((u_char *));
|
||||
void print_mode_sense __P((void));
|
||||
void usage __P((void));
|
||||
|
||||
#define N2(c, d) (((c) << 8) | (d))
|
||||
#define N3(b, c, d) (((b) << 16) | N2(c, d))
|
||||
#define N4(a, b, c, d) (((a) << 24) | N3(b, c, d))
|
||||
|
||||
int sense_pctl;
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
extern char *optarg;
|
||||
int ch, readonly;
|
||||
|
||||
readonly = 0;
|
||||
sense_pctl = SCSI_MSENSE_PCTL_CUR;
|
||||
while ((ch = getopt(argc, argv, "rp:")) != EOF) {
|
||||
switch(ch) {
|
||||
case 'r':
|
||||
readonly = 1;
|
||||
break;
|
||||
case 'p': /* mode sense page control */
|
||||
switch (*optarg) {
|
||||
case 'c':
|
||||
sense_pctl = SCSI_MSENSE_PCTL_CUR;
|
||||
break;
|
||||
case 'd':
|
||||
sense_pctl = SCSI_MSENSE_PCTL_DFLT;
|
||||
break;
|
||||
case 's':
|
||||
sense_pctl = SCSI_MSENSE_PCTL_SAVED;
|
||||
break;
|
||||
case 'v':
|
||||
(void)printf(
|
||||
"*** note: for variable parameters, 1-bit means ``can write here''\n");
|
||||
sense_pctl = SCSI_MSENSE_PCTL_VAR;
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc != 1)
|
||||
usage();
|
||||
|
||||
device = *argv;
|
||||
fd = open(device, readonly ? O_RDONLY : O_RDWR, 0);
|
||||
if (fd < 0) {
|
||||
(void)fprintf(stderr,
|
||||
"scsiformat: %s: %s\n", device, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
print_inquiry();
|
||||
print_capacity();
|
||||
print_mode_sense();
|
||||
|
||||
if (!readonly)
|
||||
do_format();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy a counted string, trimming trailing blanks, and turning the
|
||||
* result into a C-style string.
|
||||
*/
|
||||
void
|
||||
scsi_str(src, dst, len)
|
||||
register char *src, *dst;
|
||||
register int len;
|
||||
{
|
||||
|
||||
while (src[len - 1] == ' ') {
|
||||
if (--len == 0) {
|
||||
*dst = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
bcopy(src, dst, len);
|
||||
dst[len] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
print_inquiry()
|
||||
{
|
||||
register struct scsi_inq_ansi *si;
|
||||
int ver;
|
||||
struct scsi_inquiry inqbuf;
|
||||
char vendor[10], product[17], rev[5];
|
||||
static struct scsi_cdb inq = {
|
||||
CMD_INQUIRY, 0, 0, 0, sizeof(inqbuf), 0
|
||||
};
|
||||
|
||||
do_command(fd, &inq, &inqbuf, sizeof(inqbuf));
|
||||
(void)printf("%s: ", device);
|
||||
|
||||
ver = (inqbuf.si_version >> VER_ANSI_SHIFT) & VER_ANSI_MASK;
|
||||
if (ver != 1 && ver != 2) {
|
||||
(void)printf("type 0x%x, qual 0x%x, ver 0x%x (ansi %d)\n",
|
||||
inqbuf.si_type, inqbuf.si_qual, inqbuf.si_version, ver);
|
||||
return;
|
||||
}
|
||||
si = (struct scsi_inq_ansi *)&inqbuf;
|
||||
switch (si->si_type & TYPE_TYPE_MASK) {
|
||||
|
||||
case TYPE_DAD:
|
||||
(void)printf("(disk)");
|
||||
break;
|
||||
|
||||
case TYPE_WORM:
|
||||
(void)printf("(WORM)");
|
||||
break;
|
||||
|
||||
case TYPE_ROM:
|
||||
(void)printf("(CD-ROM)");
|
||||
break;
|
||||
|
||||
case TYPE_MO:
|
||||
(void)printf("(MO-DISK)");
|
||||
break;
|
||||
|
||||
case TYPE_JUKEBOX:
|
||||
(void)printf("(jukebox)");
|
||||
break;
|
||||
|
||||
default:
|
||||
(void)printf("(??)");
|
||||
break;
|
||||
}
|
||||
scsi_str(si->si_vendor, vendor, sizeof(si->si_vendor));
|
||||
scsi_str(si->si_product, product, sizeof(si->si_product));
|
||||
scsi_str(si->si_rev, rev, sizeof(si->si_rev));
|
||||
(void)printf(" %s %s rev %s:", vendor, product, rev);
|
||||
}
|
||||
|
||||
void
|
||||
print_capacity()
|
||||
{
|
||||
struct scsi_rc rc; /* for READ CAPACITY */
|
||||
static struct scsi_cdb cap = { CMD_READ_CAPACITY };
|
||||
|
||||
do_command(fd, &cap, &rc, sizeof(rc));
|
||||
(void)printf(" %d blocks of %d bytes each\n",
|
||||
N4(rc.rc_lbah, rc.rc_lbahm, rc.rc_lbalm, rc.rc_lbal) + 1,
|
||||
N4(rc.rc_blh, rc.rc_blhm, rc.rc_bllm, rc.rc_bll));
|
||||
}
|
||||
|
||||
void
|
||||
print_mode_sense()
|
||||
{
|
||||
register u_char *cp, *ep;
|
||||
register struct scsi_ms_bd *bd;
|
||||
register int n, i, l, len, bdlen;
|
||||
#ifdef TEN_BYTE_SENSE
|
||||
struct {
|
||||
struct scsi_ms10 ms;
|
||||
u_char p[1023 - sizeof(struct scsi_ms10)];
|
||||
} msbuf;
|
||||
static struct scsi_cdb modesense = {
|
||||
CMD_MODE_SENSE10, SCSI_MSENSE_DBD, 0, 0, 0, 0, 0,
|
||||
sizeof(msbuf) >> 8, sizeof (msbuf), 0
|
||||
};
|
||||
|
||||
CDB10(&modesense)->cdb_lbam = sense_pctl | SCSI_MS_PC_ALL;
|
||||
do_command(fd, &modesense, &msbuf, sizeof(msbuf));
|
||||
len = N2(msbuf.ms.ms_lenh, msbuf.ms.ms_lenl);
|
||||
bdlen = N2(msbuf.ms.ms_bdlh, msbuf.ms.ms_bdll);
|
||||
#else
|
||||
struct {
|
||||
struct scsi_ms6 ms;
|
||||
u_char p[255 - sizeof(struct scsi_ms6)];
|
||||
} msbuf;
|
||||
static struct scsi_cdb modesense = {
|
||||
CMD_MODE_SENSE6, 0, 0, 0, sizeof(msbuf), 0
|
||||
};
|
||||
|
||||
CDB6(&modesense)->cdb_lbam = sense_pctl | SCSI_MS_PC_ALL;
|
||||
do_command(fd, &modesense, &msbuf, sizeof(msbuf));
|
||||
len = msbuf.ms.ms_len;
|
||||
bdlen = msbuf.ms.ms_bdl;
|
||||
#endif
|
||||
(void)printf("\n%d bytes of mode sense data. ", len);
|
||||
(void)printf("medium type 0x%x, %swrite protected\n",
|
||||
msbuf.ms.ms_mt, msbuf.ms.ms_dsp & SCSI_MS_DSP_WP ? "" : "not ");
|
||||
if ((n = bdlen) != 0) {
|
||||
bd = (struct scsi_ms_bd *)msbuf.p;
|
||||
for (n /= sizeof(*bd); --n >= 0; bd++) {
|
||||
(void)printf("\tdensity code 0x%x, ", bd->bd_dc);
|
||||
i = N3(bd->bd_nbh, bd->bd_nbm, bd->bd_nbl);
|
||||
l = N3(bd->bd_blh, bd->bd_blm, bd->bd_bll);
|
||||
if (i)
|
||||
(void)printf("%d blocks of length %d\n", i, l);
|
||||
else
|
||||
(void)printf("all blocks of length %d\n", l);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Sense header lengths includes the sense header, while mode page
|
||||
* lengths do not ... let's hear it for consistency!
|
||||
*/
|
||||
cp = msbuf.p + bdlen;
|
||||
ep = msbuf.p + len - sizeof(msbuf.ms);
|
||||
while (cp < ep)
|
||||
cp = print_mode_page(cp);
|
||||
}
|
||||
|
||||
void
|
||||
prflags(v, cp)
|
||||
int v;
|
||||
register const char *cp;
|
||||
{
|
||||
register const char *np;
|
||||
char f, sep;
|
||||
|
||||
for (sep = '<'; (f = *cp++) != 0; cp = np) {
|
||||
for (np = cp; *np >= ' ';)
|
||||
np++;
|
||||
if ((v & (1 << (f - 1))) == 0)
|
||||
continue;
|
||||
printf("%c%.*s", sep, np - cp, cp);
|
||||
sep = ',';
|
||||
}
|
||||
if (sep != '<')
|
||||
putchar('>');
|
||||
}
|
||||
|
||||
static char *
|
||||
cache_policy(x)
|
||||
int x;
|
||||
{
|
||||
static char rsvd[30];
|
||||
|
||||
switch (x) {
|
||||
|
||||
case SCSI_CACHE_DEFAULT:
|
||||
return ("default");
|
||||
|
||||
case SCSI_CACHE_KEEPPF:
|
||||
return ("toss cmd data, save prefetch");
|
||||
|
||||
case SCSI_CACHE_KEEPCMD:
|
||||
return ("toss prefetch data, save cmd");
|
||||
|
||||
default:
|
||||
(void)sprintf(rsvd, "reserved %d", x);
|
||||
return (rsvd);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
u_char *
|
||||
print_mode_page(cp)
|
||||
u_char *cp;
|
||||
{
|
||||
register struct scsi_ms_page_hdr *mp;
|
||||
int len, code, i;
|
||||
u_char *tp;
|
||||
const char *s;
|
||||
|
||||
mp = (struct scsi_ms_page_hdr *)cp;
|
||||
code = mp->mp_psc & SCSI_MS_PC_MASK;
|
||||
len = mp->mp_len;
|
||||
(void)printf("\npage type %d%s (%d bytes): ",
|
||||
code, mp->mp_psc & SCSI_MS_MP_SAVEABLE ? " (saveable)" : "", len);
|
||||
switch (code) {
|
||||
|
||||
case SCSI_MS_PC_RWERRREC:
|
||||
#define rw ((struct scsi_page_rwerrrec *)(mp + 1))
|
||||
(void)printf("Read/Write Error Recovery parameters.\n");
|
||||
(void)printf("\tflags = 0x%x", rw->rw_flags);
|
||||
prflags(rw->rw_flags,
|
||||
"\10AWRE\7ARRE\6TB\5RC\4EER\3PER\2DTE\1DCR");
|
||||
(void)printf(",\n\t%d read retries, %d correction span bits,\n",
|
||||
rw->rw_read_retry, rw->rw_corr_span);
|
||||
(void)printf("\t%d head offsets, %d data strobe offsets%s\n",
|
||||
rw->rw_hd_off, rw->rw_ds_off, len > 6 ? "," : ".");
|
||||
if (len <= 6)
|
||||
break;
|
||||
(void)printf("\t%d write retries, ", rw->rw_write_retry);
|
||||
i = N2(rw->rw_rtlh, rw->rw_rtll);
|
||||
if (i != 0xffff)
|
||||
(void)printf("%d", i);
|
||||
else
|
||||
(void)printf("no");
|
||||
(void)printf(" recovery time limit.\n");
|
||||
break;
|
||||
#undef rw
|
||||
|
||||
case SCSI_MS_PC_DR:
|
||||
#define dr ((struct scsi_page_dr *)(mp + 1))
|
||||
(void)printf("Disconnect/Reconnect control.\n");
|
||||
(void)printf("\tbuffer full ratio %d, buffer empty ratio %d,\n",
|
||||
dr->dr_full, dr->dr_empty);
|
||||
(void)printf("\ttime limits: %d bus inactivity, ",
|
||||
N2(dr->dr_inacth, dr->dr_inactl));
|
||||
(void)printf("%d disconnect, %d connect.\n",
|
||||
N2(dr->dr_disconh, dr->dr_disconl),
|
||||
N2(dr->dr_conh, dr->dr_conl));
|
||||
(void)printf("\tmaximum burst size %d,\n",
|
||||
N2(dr->dr_bursth, dr->dr_burstl));
|
||||
switch (dr->dr_dtdc & SCSI_DR_DTDC_MASK) {
|
||||
case SCSI_DR_DTDC_NONE:
|
||||
s = "never";
|
||||
break;
|
||||
case SCSI_DR_DTDC_NOTDATA:
|
||||
s = "during data transfer";
|
||||
break;
|
||||
case SCSI_DR_DTDC_RSVD:
|
||||
s = "???";
|
||||
break;
|
||||
case SCSI_DR_DTDC_NOTD2:
|
||||
s = "during and after data transfer";
|
||||
break;
|
||||
}
|
||||
(void)printf("\tsuppress disconnect %s.\n", s);
|
||||
break;
|
||||
#undef dr
|
||||
|
||||
case SCSI_MS_PC_FMT:
|
||||
#define fmt ((struct scsi_page_fmt *)(mp + 1))
|
||||
(void)printf("Format parameters.\n");
|
||||
(void)printf("\t%d tracks/zone, %d alt.sect./zone, ",
|
||||
N2(fmt->fmt_tpzh, fmt->fmt_tpzl),
|
||||
N2(fmt->fmt_aspzh, fmt->fmt_aspzl));
|
||||
(void)printf("%d alt.tracks/zone,\n\t%d alt.tracks/vol., ",
|
||||
N2(fmt->fmt_atpzh, fmt->fmt_atpzl),
|
||||
N2(fmt->fmt_atpvh, fmt->fmt_atpvl));
|
||||
(void)printf("%d sectors/track, %d bytes/phys.sector,\n",
|
||||
N2(fmt->fmt_spth, fmt->fmt_sptl),
|
||||
N2(fmt->fmt_dbppsh, fmt->fmt_dbppsl));
|
||||
(void)printf("\tinterleave %d, track skew %d, cyl.skew %d,\n",
|
||||
N2(fmt->fmt_ilh, fmt->fmt_ill),
|
||||
N2(fmt->fmt_tsfh, fmt->fmt_tsfl),
|
||||
N2(fmt->fmt_csfh, fmt->fmt_csfl));
|
||||
(void)printf("\tdrive flags 0x%x", fmt->fmt_flags);
|
||||
prflags(fmt->fmt_flags, "\10SSEC\7HSEC\6RMB\5SURF");
|
||||
(void)printf(".\n");
|
||||
break;
|
||||
#undef fmt
|
||||
|
||||
case SCSI_MS_PC_RDGEOM:
|
||||
#define rd ((struct scsi_page_rdgeom *)(mp + 1))
|
||||
(void)printf("Disk Geometry parameters.\n");
|
||||
(void)printf("\t%d cylinders, %d heads,\n",
|
||||
N3(rd->rd_ncylh, rd->rd_ncylm, rd->rd_ncyll),
|
||||
rd->rd_nheads);
|
||||
(void)printf("\tstart write precompensation at cyl %d,\n",
|
||||
N3(rd->rd_wpcylh, rd->rd_wpcylm, rd->rd_wpcyll));
|
||||
(void)printf("\tstart reduced write current at cyl %d,\n",
|
||||
N3(rd->rd_rwcylh, rd->rd_rwcylm, rd->rd_rwcyll));
|
||||
(void)printf("\tseek step rate %f us, landing zone cyl %d,\n",
|
||||
N2(rd->rd_steph, rd->rd_stepl) * 0.1,
|
||||
N3(rd->rd_lcylh, rd->rd_lcylm, rd->rd_lcyll));
|
||||
switch (rd->rd_rpl & SCSI_RD_RPL_MASK) {
|
||||
case SCSI_RD_RPL_NONE:
|
||||
s = "disabled or unsupported";
|
||||
break;
|
||||
case SCSI_RD_RPL_SLAVE:
|
||||
s = "slave";
|
||||
break;
|
||||
case SCSI_RD_RPL_MASTER:
|
||||
s = "master";
|
||||
break;
|
||||
case SCSI_RD_RPL_MCONTROL:
|
||||
s = "master control";
|
||||
break;
|
||||
}
|
||||
(void)printf("\trotational synch %s, offset %d/256%s\n",
|
||||
s, rd->rd_roff, len > 18 ? "," : ".");
|
||||
if (len > 18)
|
||||
(void)printf("\trotation %d rpm.\n",
|
||||
N2(rd->rd_rpmh, rd->rd_rpml));
|
||||
break;
|
||||
#undef rd
|
||||
|
||||
case SCSI_MS_PC_VERRREC:
|
||||
#define v ((struct scsi_page_verrrec *)(mp + 1))
|
||||
(void)printf("Verify Error Recovery parameters.\n");
|
||||
(void)printf("\tflags = 0x%x", v->v_flags);
|
||||
prflags(v->v_flags, "\4EER\3PER\2DTE\1DCR");
|
||||
(void)printf(",\n\t%d verify retries, %d %s span bits,\n\t",
|
||||
v->v_verify_retry, v->v_corr_span, "correction");
|
||||
(void)printf("%d recovery time limit.\n",
|
||||
N2(v->v_rtlh, v->v_rtll));
|
||||
break;
|
||||
#undef v
|
||||
|
||||
case SCSI_MS_PC_CACHE:
|
||||
#define cache ((struct scsi_page_cache *)(mp + 1))
|
||||
(void)printf("Caching Page.\n");
|
||||
(void)printf("\tflags = 0x%x", cache->cache_flags);
|
||||
prflags(cache->cache_flags, "\3WCE\2MF\1RCD");
|
||||
(void)printf(
|
||||
",\n\tread retention = %s, write retention = %s,\n",
|
||||
cache_policy(SCSI_CACHE_RDPOLICY(cache->cache_reten)),
|
||||
cache_policy(SCSI_CACHE_WRPOLICY(cache->cache_reten)));
|
||||
(void)printf("\tdisable prefetch transfer length = %d,\n",
|
||||
N2(cache->cache_dptlh, cache->cache_dptll));
|
||||
(void)printf("\tmin prefetch = %d, max prefetch = %d, ",
|
||||
N2(cache->cache_minpfh, cache->cache_minpfl),
|
||||
N2(cache->cache_maxpfh, cache->cache_maxpfl));
|
||||
(void)printf("max prefetch ceiling = %d.\n",
|
||||
N2(cache->cache_mpch, cache->cache_mpcl));
|
||||
break;
|
||||
#undef cache
|
||||
|
||||
case SCSI_MS_PC_CTLMODE:
|
||||
#define cm ((struct scsi_page_ctlmode *)(mp + 1))
|
||||
(void)printf("Control Mode Page.\n");
|
||||
(void)printf("\t%s report log-activity error conditions,\n",
|
||||
cm->cm_rlec & SCSI_CM_RLEC ? "do" : "do not");
|
||||
(void)printf("\tqueue algorithm modifier = %d, flags = 0x%x",
|
||||
SCSI_CM_QMOD(cm->cm_qctl),
|
||||
cm->cm_qctl & (SCSI_CM_QERR|SCSI_CM_DQUE));
|
||||
prflags(cm->cm_qctl, "\2QERR\1DQUE");
|
||||
(void)printf(",\n\tECA/AEN flags = 0x%x", cm->cm_ecaaen);
|
||||
prflags(cm->cm_ecaaen, "\10ECA\3RAENP\2UUAENP\1EAENP");
|
||||
(void)printf(", AEN holdoff period = %d ms.\n",
|
||||
N2(cm->cm_aenholdh, cm->cm_aenholdl));
|
||||
break;
|
||||
#undef cm
|
||||
|
||||
/*
|
||||
* Vendor Unique, but what the heck.
|
||||
*/
|
||||
case SCSI_MS_PC_CDCCACHECTL:
|
||||
#define ccm ((struct scsi_page_CDCcachectlmode *)(mp + 1))
|
||||
(void)printf("CDC-specific Cache Control Mode Page.\n");
|
||||
(void)printf("\tflags = 0x%x", ccm->ccm_flags);
|
||||
prflags(ccm->ccm_flags, "\7WIE\5ENABLE");
|
||||
(void)printf(", table size = %d, prefetch threshold = %d\n",
|
||||
SCSI_CDC_CCM_TBLSZ(ccm->ccm_flags),
|
||||
ccm->ccm_pfthresh);
|
||||
(void)printf("\tmaximum %s = %d, maximum %s = %d,\n",
|
||||
"threshold", ccm->ccm_maxthresh,
|
||||
"prefetch multiplier", ccm->ccm_maxpfmult);
|
||||
(void)printf("\tminimum %s = %d, minimum %s = %d.\n",
|
||||
"threshold", ccm->ccm_minthresh,
|
||||
"prefetch multiplier", ccm->ccm_minpfmult);
|
||||
break;
|
||||
#undef ccm
|
||||
|
||||
default:
|
||||
(void)printf("Unknown page type.");
|
||||
for (tp = cp + sizeof(*mp), i = 0; i < len; ++i) {
|
||||
if ((i & 7) == 0)
|
||||
(void)printf("\n\t%2d: ", i);
|
||||
(void)printf(" %02x", *tp++);
|
||||
}
|
||||
(void)printf(".\n");
|
||||
break;
|
||||
}
|
||||
return (cp + sizeof(*mp) + len);
|
||||
}
|
||||
|
||||
void
|
||||
pr_sense(fd)
|
||||
int fd;
|
||||
{
|
||||
static struct scsi_fmt_sense s;
|
||||
register struct scsi_sense *sn;
|
||||
|
||||
if (ioctl(fd, SDIOCSENSE, &s) < 0)
|
||||
(void)fprintf(stderr,
|
||||
"scsiformat: SDIOCSENSE: %s\n", strerror(errno));
|
||||
|
||||
(void)printf("scsi status 0x%x", s.status);
|
||||
if (s.status & STS_CHECKCOND) {
|
||||
sn = (struct scsi_sense *)s.sense;
|
||||
|
||||
(void)printf(" sense class %d, code %d",
|
||||
SENSE_ECLASS(sn), SENSE_ECODE(sn));
|
||||
if (SENSE_ISXSENSE(sn)) {
|
||||
(void)printf(", key %d", XSENSE_KEY(sn));
|
||||
if (XSENSE_IVALID(sn))
|
||||
(void)printf(", blk %d", XSENSE_INFO(sn));
|
||||
}
|
||||
}
|
||||
(void)printf("\n");
|
||||
}
|
||||
|
||||
void
|
||||
do_format()
|
||||
{
|
||||
struct {
|
||||
struct scsi_ms6 ms; /* mode select header */
|
||||
struct scsi_ms_bd bd; /* block descriptor */
|
||||
struct scsi_ms_page_hdr mp; /* ctl mode page hdr */
|
||||
struct scsi_page_ctlmode cm; /* ctl mode page */
|
||||
u_char pad[4]; /* ??? */
|
||||
} msel;
|
||||
u_char fmtbuf[128];
|
||||
static struct scsi_cdb modeselect = {
|
||||
CMD_MODE_SELECT6,
|
||||
SCSI_MSEL_SCSI2_DATA | SCSI_MSEL_SAVEPAGES, 0, 0,
|
||||
sizeof(msel), 0
|
||||
};
|
||||
static struct scsi_cdb format = { CMD_FORMAT_UNIT };
|
||||
|
||||
/* want mostly 0s; set them all zero here */
|
||||
bzero(&msel, sizeof(msel));
|
||||
|
||||
/* one block descriptor */
|
||||
msel.ms.ms_bdl = sizeof(struct scsi_ms_bd);
|
||||
|
||||
/* block length = 512 bytes */
|
||||
msel.bd.bd_blm = 512 / 256;
|
||||
msel.bd.bd_bll = 512 % 256;
|
||||
|
||||
/*
|
||||
* In the following, the mystery pad region is copied from
|
||||
* the original driver. I have no idea what it is for.
|
||||
* (Anyone got SCSI-2 documents?)
|
||||
*/
|
||||
|
||||
/* mode page parameters: report log-activity exception conditions */
|
||||
msel.mp.mp_psc = SCSI_MS_PC_CTLMODE;
|
||||
msel.mp.mp_len = sizeof(msel.cm) + sizeof(msel.pad);
|
||||
msel.cm.cm_rlec = SCSI_CM_RLEC;
|
||||
|
||||
do_command(fd, &modeselect, &msel, sizeof(msel));
|
||||
|
||||
bzero(fmtbuf, sizeof(fmtbuf));
|
||||
do_command(fd, &format, fmtbuf, sizeof(fmtbuf));
|
||||
}
|
||||
|
||||
void
|
||||
do_command(fd, cdb, buf, len)
|
||||
int fd;
|
||||
struct scsi_cdb *cdb;
|
||||
void *buf;
|
||||
int len;
|
||||
{
|
||||
static int on = 1, off = 0;
|
||||
int user, ret;
|
||||
|
||||
bzero(buf, len);
|
||||
if (ioctl(fd, SDIOCSFORMAT, &on) < 0) {
|
||||
(void)fprintf(stderr,
|
||||
"scsiformat: SDIOCSFORMAT (on): %s\n", strerror(errno));
|
||||
if (ioctl(fd, SDIOCGFORMAT, &user) == 0 && user != 0)
|
||||
(void)fprintf(stderr, "scsiformat: pid %d has it\n",
|
||||
user);
|
||||
return;
|
||||
}
|
||||
ret = ioctl(fd, SDIOCSCSICOMMAND, cdb);
|
||||
#ifdef COMPAT_HPSCSI
|
||||
if (ret < 0) {
|
||||
static const char scsicmdlen[8] = { 6, 10, 0, 0, 0, 12, 0, 0 };
|
||||
#define SCSICMDLEN(cmd) scsicmdlen[(cmd) >> 5]
|
||||
struct scsi_fmt_cdb {
|
||||
int len;
|
||||
u_char cdb[28];
|
||||
} sc;
|
||||
#define OSDIOCSCSICOMMAND _IOW('S', 0x3, struct scsi_fmt_cdb)
|
||||
|
||||
sc.len = SCSICMDLEN(cdb->cdb_bytes[0]);
|
||||
bcopy(cdb->cdb_bytes, sc.cdb, sc.len);
|
||||
ret = ioctl(fd, OSDIOCSCSICOMMAND, &sc);
|
||||
}
|
||||
#endif
|
||||
if (ret < 0)
|
||||
(void)fprintf(stderr,
|
||||
"scsiformat: SDIOCSCSICOMMAND: %s\n", strerror(errno));
|
||||
else if (read(fd, buf, len) < 0) {
|
||||
(void)fprintf(stderr,
|
||||
"scsiformat: read: %s\n", strerror(errno));
|
||||
pr_sense(fd);
|
||||
}
|
||||
|
||||
if (ioctl(fd, SDIOCSFORMAT, &off) < 0)
|
||||
(void)fprintf(stderr,
|
||||
"scsiformat: SDIOCSFORMAT (off): %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
void
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr, "usage: scsiformat [-r] [-p c|d|s|v] device\n");
|
||||
exit(1);
|
||||
}
|
162
sbin/shutdown/shutdown.8
Normal file
162
sbin/shutdown/shutdown.8
Normal file
@ -0,0 +1,162 @@
|
||||
.\" Copyright (c) 1988, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. 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.
|
||||
.\"
|
||||
.\" @(#)shutdown.8 8.2 (Berkeley) 4/27/95
|
||||
.\"
|
||||
.Dd April 27, 1995
|
||||
.Dt SHUTDOWN 8
|
||||
.Os BSD 4
|
||||
.Sh NAME
|
||||
.Nm shutdown
|
||||
.Nd "close down the system at a given time"
|
||||
.Sh SYNOPSIS
|
||||
.Nm shutdown
|
||||
.Op Fl
|
||||
.Op Fl fhkrn
|
||||
.Ar time
|
||||
.Op Ar warning-message ...
|
||||
.Sh DESCRIPTION
|
||||
.Nm Shutdown
|
||||
provides an automated shutdown procedure for super-users
|
||||
to nicely notify users when the system is shutting down,
|
||||
saving them from system administrators, hackers, and gurus, who
|
||||
would otherwise not bother with such niceties.
|
||||
.Pp
|
||||
Available friendlinesses:
|
||||
.Bl -tag -width time
|
||||
.It Fl f
|
||||
.Nm Shutdown
|
||||
arranges, in the manner of
|
||||
.Xr fastboot 8 ,
|
||||
for the file systems
|
||||
.Em not to be
|
||||
checked on reboot.
|
||||
.It Fl h
|
||||
The system is halted at the specified
|
||||
.Ar time
|
||||
when
|
||||
.Nm shutdown
|
||||
execs
|
||||
.Xr halt 8 .
|
||||
.It Fl k
|
||||
Kick everybody off.
|
||||
The
|
||||
.Fl k
|
||||
option
|
||||
does not actually halt the system, but leaves the
|
||||
system multi-user with logins disabled (for all but super-user).
|
||||
.It Fl n
|
||||
Prevent the normal
|
||||
.Xr sync 2
|
||||
before stopping.
|
||||
.It Fl r
|
||||
.Nm Shutdown
|
||||
execs
|
||||
.Xr reboot 8
|
||||
at the specified
|
||||
.Ar time .
|
||||
.It Ar time
|
||||
.Ar Time
|
||||
is the time at which
|
||||
.Nm shutdown
|
||||
will bring the system down and
|
||||
may be the word
|
||||
.Ar now
|
||||
(indicating an immediate shutdown) or
|
||||
specify a future time in one of two formats:
|
||||
.Ar +number ,
|
||||
or
|
||||
.Ar yymmddhhmm ,
|
||||
where the year, month, and day may be defaulted
|
||||
to the current system values. The first form brings the system down in
|
||||
.Ar number
|
||||
minutes and the second at the absolute time specified.
|
||||
.It Ar warning-message
|
||||
Any other arguments comprise the warning message that is broadcast
|
||||
to users currently logged into the system.
|
||||
.It Fl
|
||||
If
|
||||
.Ql Fl
|
||||
is supplied as an option, the warning message is read from the standard
|
||||
input.
|
||||
.El
|
||||
.Pp
|
||||
At intervals, becoming more frequent as apocalypse approaches
|
||||
and starting at ten hours before shutdown, warning messages are displayed
|
||||
on the terminals of all users logged in. Five minutes before
|
||||
shutdown, or immediately if shutdown is in less than 5 minutes,
|
||||
logins are disabled by creating
|
||||
.Pa /etc/nologin
|
||||
and copying the
|
||||
warning message there. If this file exists when a user attempts to
|
||||
log in,
|
||||
.Xr login 1
|
||||
prints its contents and exits. The file is
|
||||
removed just before
|
||||
.Nm shutdown
|
||||
exits.
|
||||
.Pp
|
||||
At shutdown time a message is written in the system log, containing the
|
||||
time of shutdown, who initiated the shutdown and the reason.
|
||||
A terminate
|
||||
signal is then sent to
|
||||
.Xr init
|
||||
to bring the system down to single-user state (depending on above
|
||||
options).
|
||||
The time of the shutdown and the warning message
|
||||
are placed in
|
||||
.Pa /etc/nologin
|
||||
and should be used to
|
||||
inform the users about when the system will be back up
|
||||
and why it is going down (or anything else).
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/nologin -compact
|
||||
.It Pa /etc/nologin
|
||||
tells login not to let anyone log in
|
||||
.It Pa /fastboot
|
||||
tells
|
||||
.Xr rc 8
|
||||
not to run fsck when rebooting
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr login 1 ,
|
||||
.Xr wall 1 ,
|
||||
.Xr fastboot 8 ,
|
||||
.Xr halt 8 ,
|
||||
.Xr reboot 8
|
||||
.Sh BACKWARD COMPATIBILITY
|
||||
The hours and minutes in the second time format may be separated by
|
||||
a colon (``:'') for backward compatibility.
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command appeared in
|
||||
.Bx 4.0 .
|
493
sbin/shutdown/shutdown.c
Normal file
493
sbin/shutdown/shutdown.c
Normal file
@ -0,0 +1,493 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1988, 1990, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)shutdown.c 8.4 (Berkeley) 4/28/95";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <tzfile.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "pathnames.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#undef _PATH_NOLOGIN
|
||||
#define _PATH_NOLOGIN "./nologin"
|
||||
#undef _PATH_FASTBOOT
|
||||
#define _PATH_FASTBOOT "./fastboot"
|
||||
#endif
|
||||
|
||||
#define H *60*60
|
||||
#define M *60
|
||||
#define S *1
|
||||
#define NOLOG_TIME 5*60
|
||||
struct interval {
|
||||
int timeleft, timetowait;
|
||||
} tlist[] = {
|
||||
10 H, 5 H, 5 H, 3 H, 2 H, 1 H, 1 H, 30 M,
|
||||
30 M, 10 M, 20 M, 10 M, 10 M, 5 M, 5 M, 3 M,
|
||||
2 M, 1 M, 1 M, 30 S, 30 S, 30 S,
|
||||
0, 0,
|
||||
};
|
||||
#undef H
|
||||
#undef M
|
||||
#undef S
|
||||
|
||||
static time_t offset, shuttime;
|
||||
static int dofast, dohalt, doreboot, killflg, mbuflen;
|
||||
static char *nosync, *whom, mbuf[BUFSIZ];
|
||||
|
||||
void badtime __P((void));
|
||||
void die_you_gravy_sucking_pig_dog __P((void));
|
||||
void doitfast __P((void));
|
||||
void finish __P((int));
|
||||
void getoffset __P((char *));
|
||||
void loop __P((void));
|
||||
void nolog __P((void));
|
||||
void timeout __P((int));
|
||||
void timewarn __P((int));
|
||||
void usage __P((void));
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
extern int optind;
|
||||
register char *p, *endp;
|
||||
struct passwd *pw;
|
||||
int arglen, ch, len, readstdin;
|
||||
|
||||
#ifndef DEBUG
|
||||
if (geteuid()) {
|
||||
(void)fprintf(stderr, "shutdown: NOT super-user\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
nosync = NULL;
|
||||
readstdin = 0;
|
||||
while ((ch = getopt(argc, argv, "-fhknr")) != EOF)
|
||||
switch (ch) {
|
||||
case '-':
|
||||
readstdin = 1;
|
||||
break;
|
||||
case 'f':
|
||||
dofast = 1;
|
||||
break;
|
||||
case 'h':
|
||||
dohalt = 1;
|
||||
break;
|
||||
case 'k':
|
||||
killflg = 1;
|
||||
break;
|
||||
case 'n':
|
||||
nosync = "-n";
|
||||
break;
|
||||
case 'r':
|
||||
doreboot = 1;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 1)
|
||||
usage();
|
||||
|
||||
if (dofast && nosync) {
|
||||
(void)fprintf(stderr,
|
||||
"shutdown: incompatible switches -f and -n.\n");
|
||||
usage();
|
||||
}
|
||||
if (doreboot && dohalt) {
|
||||
(void)fprintf(stderr,
|
||||
"shutdown: incompatible switches -h and -r.\n");
|
||||
usage();
|
||||
}
|
||||
getoffset(*argv++);
|
||||
|
||||
if (*argv) {
|
||||
for (p = mbuf, len = sizeof(mbuf); *argv; ++argv) {
|
||||
arglen = strlen(*argv);
|
||||
if ((len -= arglen) <= 2)
|
||||
break;
|
||||
if (p != mbuf)
|
||||
*p++ = ' ';
|
||||
memmove(p, *argv, arglen);
|
||||
p += arglen;
|
||||
}
|
||||
*p = '\n';
|
||||
*++p = '\0';
|
||||
}
|
||||
|
||||
if (readstdin) {
|
||||
p = mbuf;
|
||||
endp = mbuf + sizeof(mbuf) - 2;
|
||||
for (;;) {
|
||||
if (!fgets(p, endp - p + 1, stdin))
|
||||
break;
|
||||
for (; *p && p < endp; ++p);
|
||||
if (p == endp) {
|
||||
*p = '\n';
|
||||
*++p = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
mbuflen = strlen(mbuf);
|
||||
|
||||
if (offset)
|
||||
(void)printf("Shutdown at %.24s.\n", ctime(&shuttime));
|
||||
else
|
||||
(void)printf("Shutdown NOW!\n");
|
||||
|
||||
if (!(whom = getlogin()))
|
||||
whom = (pw = getpwuid(getuid())) ? pw->pw_name : "???";
|
||||
|
||||
#ifdef DEBUG
|
||||
(void)putc('\n', stdout);
|
||||
#else
|
||||
(void)setpriority(PRIO_PROCESS, 0, PRIO_MIN);
|
||||
{
|
||||
int forkpid;
|
||||
|
||||
forkpid = fork();
|
||||
if (forkpid == -1) {
|
||||
perror("shutdown: fork");
|
||||
exit(1);
|
||||
}
|
||||
if (forkpid) {
|
||||
(void)printf("shutdown: [pid %d]\n", forkpid);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
openlog("shutdown", LOG_CONS, LOG_AUTH);
|
||||
loop();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
void
|
||||
loop()
|
||||
{
|
||||
struct interval *tp;
|
||||
u_int sltime;
|
||||
int logged;
|
||||
|
||||
if (offset <= NOLOG_TIME) {
|
||||
logged = 1;
|
||||
nolog();
|
||||
}
|
||||
else
|
||||
logged = 0;
|
||||
tp = tlist;
|
||||
if (tp->timeleft < offset)
|
||||
(void)sleep((u_int)(offset - tp->timeleft));
|
||||
else {
|
||||
while (offset < tp->timeleft)
|
||||
++tp;
|
||||
/*
|
||||
* Warn now, if going to sleep more than a fifth of
|
||||
* the next wait time.
|
||||
*/
|
||||
if (sltime = offset - tp->timeleft) {
|
||||
if (sltime > tp->timetowait / 5)
|
||||
timewarn(offset);
|
||||
(void)sleep(sltime);
|
||||
}
|
||||
}
|
||||
for (;; ++tp) {
|
||||
timewarn(tp->timeleft);
|
||||
if (!logged && tp->timeleft <= NOLOG_TIME) {
|
||||
logged = 1;
|
||||
nolog();
|
||||
}
|
||||
(void)sleep((u_int)tp->timetowait);
|
||||
if (!tp->timeleft)
|
||||
break;
|
||||
}
|
||||
die_you_gravy_sucking_pig_dog();
|
||||
}
|
||||
|
||||
static jmp_buf alarmbuf;
|
||||
|
||||
void
|
||||
timewarn(timeleft)
|
||||
int timeleft;
|
||||
{
|
||||
static int first;
|
||||
static char hostname[MAXHOSTNAMELEN + 1];
|
||||
FILE *pf;
|
||||
char wcmd[MAXPATHLEN + 4];
|
||||
|
||||
if (!first++)
|
||||
(void)gethostname(hostname, sizeof(hostname));
|
||||
|
||||
/* undoc -n option to wall suppresses normal wall banner */
|
||||
(void)snprintf(wcmd, sizeof(wcmd), "%s -n", _PATH_WALL);
|
||||
if (!(pf = popen(wcmd, "w"))) {
|
||||
syslog(LOG_ERR, "shutdown: can't find %s: %m", _PATH_WALL);
|
||||
return;
|
||||
}
|
||||
|
||||
(void)fprintf(pf,
|
||||
"\007*** %sSystem shutdown message from %s@%s ***\007\n",
|
||||
timeleft ? "": "FINAL ", whom, hostname);
|
||||
|
||||
if (timeleft > 10*60)
|
||||
(void)fprintf(pf, "System going down at %5.5s\n\n",
|
||||
ctime(&shuttime) + 11);
|
||||
else if (timeleft > 59)
|
||||
(void)fprintf(pf, "System going down in %d minute%s\n\n",
|
||||
timeleft / 60, (timeleft > 60) ? "s" : "");
|
||||
else if (timeleft)
|
||||
(void)fprintf(pf, "System going down in 30 seconds\n\n");
|
||||
else
|
||||
(void)fprintf(pf, "System going down IMMEDIATELY\n\n");
|
||||
|
||||
if (mbuflen)
|
||||
(void)fwrite(mbuf, sizeof(*mbuf), mbuflen, pf);
|
||||
|
||||
/*
|
||||
* play some games, just in case wall doesn't come back
|
||||
* probably unecessary, given that wall is careful.
|
||||
*/
|
||||
if (!setjmp(alarmbuf)) {
|
||||
(void)signal(SIGALRM, timeout);
|
||||
(void)alarm((u_int)30);
|
||||
(void)pclose(pf);
|
||||
(void)alarm((u_int)0);
|
||||
(void)signal(SIGALRM, SIG_DFL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
timeout(signo)
|
||||
int signo;
|
||||
{
|
||||
longjmp(alarmbuf, 1);
|
||||
}
|
||||
|
||||
void
|
||||
die_you_gravy_sucking_pig_dog()
|
||||
{
|
||||
|
||||
syslog(LOG_NOTICE, "%s by %s: %s",
|
||||
doreboot ? "reboot" : dohalt ? "halt" : "shutdown", whom, mbuf);
|
||||
(void)sleep(2);
|
||||
|
||||
(void)printf("\r\nSystem shutdown time has arrived\007\007\r\n");
|
||||
if (killflg) {
|
||||
(void)printf("\rbut you'll have to do it yourself\r\n");
|
||||
finish(0);
|
||||
}
|
||||
if (dofast)
|
||||
doitfast();
|
||||
#ifdef DEBUG
|
||||
if (doreboot)
|
||||
(void)printf("reboot");
|
||||
else if (dohalt)
|
||||
(void)printf("halt");
|
||||
if (nosync)
|
||||
(void)printf(" no sync");
|
||||
if (dofast)
|
||||
(void)printf(" no fsck");
|
||||
(void)printf("\nkill -HUP 1\n");
|
||||
#else
|
||||
if (doreboot) {
|
||||
execle(_PATH_REBOOT, "reboot", "-l", nosync, 0);
|
||||
syslog(LOG_ERR, "shutdown: can't exec %s: %m.", _PATH_REBOOT);
|
||||
perror("shutdown");
|
||||
}
|
||||
else if (dohalt) {
|
||||
execle(_PATH_HALT, "halt", "-l", nosync, 0);
|
||||
syslog(LOG_ERR, "shutdown: can't exec %s: %m.", _PATH_HALT);
|
||||
perror("shutdown");
|
||||
}
|
||||
(void)kill(1, SIGTERM); /* to single user */
|
||||
#endif
|
||||
finish(0);
|
||||
}
|
||||
|
||||
#define ATOI2(p) (p[0] - '0') * 10 + (p[1] - '0'); p += 2;
|
||||
|
||||
void
|
||||
getoffset(timearg)
|
||||
register char *timearg;
|
||||
{
|
||||
register struct tm *lt;
|
||||
register char *p;
|
||||
time_t now;
|
||||
|
||||
if (!strcasecmp(timearg, "now")) { /* now */
|
||||
offset = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
(void)time(&now);
|
||||
if (*timearg == '+') { /* +minutes */
|
||||
if (!isdigit(*++timearg))
|
||||
badtime();
|
||||
offset = atoi(timearg) * 60;
|
||||
shuttime = now + offset;
|
||||
return;
|
||||
}
|
||||
|
||||
/* handle hh:mm by getting rid of the colon */
|
||||
for (p = timearg; *p; ++p)
|
||||
if (!isascii(*p) || !isdigit(*p))
|
||||
if (*p == ':' && strlen(p) == 3) {
|
||||
p[0] = p[1];
|
||||
p[1] = p[2];
|
||||
p[2] = '\0';
|
||||
}
|
||||
else
|
||||
badtime();
|
||||
|
||||
unsetenv("TZ"); /* OUR timezone */
|
||||
lt = localtime(&now); /* current time val */
|
||||
|
||||
switch(strlen(timearg)) {
|
||||
case 10:
|
||||
lt->tm_year = ATOI2(timearg);
|
||||
/* FALLTHROUGH */
|
||||
case 8:
|
||||
lt->tm_mon = ATOI2(timearg);
|
||||
if (--lt->tm_mon < 0 || lt->tm_mon > 11)
|
||||
badtime();
|
||||
/* FALLTHROUGH */
|
||||
case 6:
|
||||
lt->tm_mday = ATOI2(timearg);
|
||||
if (lt->tm_mday < 1 || lt->tm_mday > 31)
|
||||
badtime();
|
||||
/* FALLTHROUGH */
|
||||
case 4:
|
||||
lt->tm_hour = ATOI2(timearg);
|
||||
if (lt->tm_hour < 0 || lt->tm_hour > 23)
|
||||
badtime();
|
||||
lt->tm_min = ATOI2(timearg);
|
||||
if (lt->tm_min < 0 || lt->tm_min > 59)
|
||||
badtime();
|
||||
lt->tm_sec = 0;
|
||||
if ((shuttime = mktime(lt)) == -1)
|
||||
badtime();
|
||||
if ((offset = shuttime - now) < 0) {
|
||||
(void)fprintf(stderr,
|
||||
"shutdown: that time is already past.\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
badtime();
|
||||
}
|
||||
}
|
||||
|
||||
#define FSMSG "fastboot file for fsck\n"
|
||||
void
|
||||
doitfast()
|
||||
{
|
||||
int fastfd;
|
||||
|
||||
if ((fastfd = open(_PATH_FASTBOOT, O_WRONLY|O_CREAT|O_TRUNC,
|
||||
0664)) >= 0) {
|
||||
(void)write(fastfd, FSMSG, sizeof(FSMSG) - 1);
|
||||
(void)close(fastfd);
|
||||
}
|
||||
}
|
||||
|
||||
#define NOMSG "\n\nNO LOGINS: System going down at "
|
||||
void
|
||||
nolog()
|
||||
{
|
||||
int logfd;
|
||||
char *ct;
|
||||
|
||||
(void)unlink(_PATH_NOLOGIN); /* in case linked to another file */
|
||||
(void)signal(SIGINT, finish);
|
||||
(void)signal(SIGHUP, finish);
|
||||
(void)signal(SIGQUIT, finish);
|
||||
(void)signal(SIGTERM, finish);
|
||||
if ((logfd = open(_PATH_NOLOGIN, O_WRONLY|O_CREAT|O_TRUNC,
|
||||
0664)) >= 0) {
|
||||
(void)write(logfd, NOMSG, sizeof(NOMSG) - 1);
|
||||
ct = ctime(&shuttime);
|
||||
(void)write(logfd, ct + 11, 5);
|
||||
(void)write(logfd, "\n\n", 2);
|
||||
(void)write(logfd, mbuf, strlen(mbuf));
|
||||
(void)close(logfd);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
finish(signo)
|
||||
int signo;
|
||||
{
|
||||
if (!killflg)
|
||||
(void)unlink(_PATH_NOLOGIN);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
badtime()
|
||||
{
|
||||
(void)fprintf(stderr, "shutdown: bad time format.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
usage()
|
||||
{
|
||||
fprintf(stderr, "usage: shutdown [-fhknr] shutdowntime [ message ]\n");
|
||||
exit(1);
|
||||
}
|
166
sbin/tunefs/tunefs.8
Normal file
166
sbin/tunefs/tunefs.8
Normal file
@ -0,0 +1,166 @@
|
||||
.\" 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. 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.
|
||||
.\"
|
||||
.\" @(#)tunefs.8 8.3 (Berkeley) 5/3/95
|
||||
.\"
|
||||
.Dd May 3, 1995
|
||||
.Dt TUNEFS 8
|
||||
.Os BSD 4.2
|
||||
.Sh NAME
|
||||
.Nm tunefs
|
||||
.Nd tune up an existing file system
|
||||
.Sh SYNOPSIS
|
||||
.Nm tunefs
|
||||
.Op Fl AN
|
||||
.Op Fl a Ar maxcontig
|
||||
.Op Fl d Ar rotdelay
|
||||
.Op Fl e Ar maxbpg
|
||||
.Op Fl m Ar minfree
|
||||
.Bk -words
|
||||
.Op Fl o Ar optimize_preference
|
||||
.Ek
|
||||
.Op Fl t Ar trackskew
|
||||
.Op Ar special | Ar filesys
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm tunefs
|
||||
program is designed to change the dynamic parameters of a file system
|
||||
which affect the layout policies.
|
||||
The
|
||||
.Fl N
|
||||
flag displays all the settable options
|
||||
(after any changes from the tuning options)
|
||||
but does not cause any of them to be changed.
|
||||
The
|
||||
.Fl A
|
||||
flag causes the values to be updated in all the alternate
|
||||
superblocks instead of just the standard superblock.
|
||||
If this option is not used,
|
||||
then use of a backup superblock by
|
||||
.Xr fsck 8
|
||||
will lose anything changed by
|
||||
.Nm tunefs .
|
||||
The
|
||||
.Fl A
|
||||
flag is ignored when the
|
||||
.Fl N
|
||||
flag is specified.
|
||||
.Pp
|
||||
The parameters which are to be changed are indicated by the flags
|
||||
given below:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl a Ar maxcontig
|
||||
This specifies the maximum number of contiguous blocks that will
|
||||
be laid out before forcing a rotational delay (see
|
||||
.Fl d
|
||||
below).
|
||||
The default value is one, since most device drivers require
|
||||
an interrupt per disk transfer.
|
||||
Device drivers that can chain several buffers together in a single
|
||||
transfer should set this to the maximum chain length.
|
||||
.It Fl d Ar rotdelay
|
||||
This specifies the expected time (in milliseconds)
|
||||
to service a transfer completion
|
||||
interrupt and initiate a new transfer on the same disk.
|
||||
It is used to decide how much rotational spacing to place between
|
||||
successive blocks in a file.
|
||||
.It Fl e Ar maxbpg
|
||||
This indicates the maximum number of blocks any single file can
|
||||
allocate out of a cylinder group before it is forced to begin
|
||||
allocating blocks from another cylinder group.
|
||||
Typically this value is set to about one quarter of the total blocks
|
||||
in a cylinder group.
|
||||
The intent is to prevent any single file from using up all the
|
||||
blocks in a single cylinder group,
|
||||
thus degrading access times for all files subsequently allocated
|
||||
in that cylinder group.
|
||||
The effect of this limit is to cause big files to do long seeks
|
||||
more frequently than if they were allowed to allocate all the blocks
|
||||
in a cylinder group before seeking elsewhere.
|
||||
For file systems with exclusively large files,
|
||||
this parameter should be set higher.
|
||||
.It Fl m Ar minfree
|
||||
This value specifies the percentage of space held back
|
||||
from normal users; the minimum free space threshold.
|
||||
The default value used is 10%.
|
||||
This value can be set to zero, however up to a factor of three
|
||||
in throughput will be lost over the performance obtained at a 10%
|
||||
threshold.
|
||||
Note that if the value is raised above the current usage level,
|
||||
users will be unable to allocate files until enough files have
|
||||
been deleted to get under the higher threshold.
|
||||
.It Fl o Ar optimize_preference
|
||||
The file system can either try to minimize the time spent
|
||||
allocating blocks, or it can attempt to minimize the space
|
||||
fragmentation on the disk.
|
||||
If the value of minfree (see above) is less than 10%,
|
||||
then the file system should optimize for space to avoid
|
||||
running out of full sized blocks.
|
||||
For values of minfree greater than or equal to 10%,
|
||||
fragmentation is unlikely to be problematical, and
|
||||
the file system can be optimized for time.
|
||||
.It Fl t Ar trackskew
|
||||
This specifies the skew in sectors from one track to the next in a cylinder.
|
||||
The default value is zero, indicating that each track in a cylinder begins at
|
||||
the same rotational position.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr fs 5 ,
|
||||
.Xr dumpfs 8 ,
|
||||
.Xr fsck 8 ,
|
||||
.Xr newfs 8 ,
|
||||
.Xr mkfs 8
|
||||
.Rs
|
||||
.%A M. McKusick
|
||||
.%A W. Joy
|
||||
.%A S. Leffler
|
||||
.%A R. Fabry
|
||||
.%T "A Fast File System for UNIX"
|
||||
.%J "ACM Transactions on Computer Systems 2"
|
||||
.%N 3
|
||||
.%P pp 181-197
|
||||
.%D August 1984
|
||||
.%O "(reprinted in the BSD System Manager's Manual, SMM:5)"
|
||||
.Re
|
||||
.Sh BUGS
|
||||
This program should work on mounted and active file systems.
|
||||
Because the super-block is not kept in the buffer cache,
|
||||
the changes will only take effect if the program
|
||||
is run on dismounted file systems.
|
||||
To change the root file system, the system must be rebooted
|
||||
after the file system is tuned.
|
||||
.Pp
|
||||
You can tune a file system, but you can't tune a fish.
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command appeared in
|
||||
.Bx 4.2 .
|
327
sbin/tunefs/tunefs.c
Normal file
327
sbin/tunefs/tunefs.c
Normal file
@ -0,0 +1,327 @@
|
||||
/*
|
||||
* 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. 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1983, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)tunefs.c 8.3 (Berkeley) 5/3/95";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* tunefs: change layout parameters to an existing file system.
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <fstab.h>
|
||||
#include <stdio.h>
|
||||
#include <paths.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* the optimization warning string template */
|
||||
#define OPTWARN "should optimize for %s with minfree %s %d%%"
|
||||
|
||||
union {
|
||||
struct fs sb;
|
||||
char pad[MAXBSIZE];
|
||||
} sbun;
|
||||
#define sblock sbun.sb
|
||||
|
||||
int fi;
|
||||
long dev_bsize = 1;
|
||||
|
||||
void bwrite(daddr_t, char *, int);
|
||||
int bread(daddr_t, char *, int);
|
||||
void getsb(struct fs *, char *);
|
||||
void usage __P((void));
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
char *cp, *special, *name;
|
||||
struct stat st;
|
||||
int i;
|
||||
int Aflag = 0, Nflag = 0;
|
||||
struct fstab *fs;
|
||||
char *chg[2], device[MAXPATHLEN];
|
||||
|
||||
argc--, argv++;
|
||||
if (argc < 2)
|
||||
usage();
|
||||
special = argv[argc - 1];
|
||||
fs = getfsfile(special);
|
||||
if (fs)
|
||||
special = fs->fs_spec;
|
||||
again:
|
||||
if (stat(special, &st) < 0) {
|
||||
if (*special != '/') {
|
||||
if (*special == 'r')
|
||||
special++;
|
||||
(void)sprintf(device, "%s/%s", _PATH_DEV, special);
|
||||
special = device;
|
||||
goto again;
|
||||
}
|
||||
err(1, "%s", special);
|
||||
}
|
||||
if ((st.st_mode & S_IFMT) != S_IFBLK &&
|
||||
(st.st_mode & S_IFMT) != S_IFCHR)
|
||||
errx(10, "%s: not a block or character device", special);
|
||||
getsb(&sblock, special);
|
||||
chg[FS_OPTSPACE] = "space";
|
||||
chg[FS_OPTTIME] = "time";
|
||||
for (; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
|
||||
for (cp = &argv[0][1]; *cp; cp++)
|
||||
switch (*cp) {
|
||||
|
||||
case 'A':
|
||||
Aflag++;
|
||||
continue;
|
||||
|
||||
case 'N':
|
||||
Nflag++;
|
||||
continue;
|
||||
|
||||
case 'a':
|
||||
name = "maximum contiguous block count";
|
||||
if (argc < 1)
|
||||
errx(10, "-a: missing %s", name);
|
||||
argc--, argv++;
|
||||
i = atoi(*argv);
|
||||
if (i < 1)
|
||||
errx(10, "%s must be >= 1 (was %s)",
|
||||
name, *argv);
|
||||
warnx("%s changes from %d to %d",
|
||||
name, sblock.fs_maxcontig, i);
|
||||
sblock.fs_maxcontig = i;
|
||||
continue;
|
||||
|
||||
case 'd':
|
||||
name =
|
||||
"rotational delay between contiguous blocks";
|
||||
if (argc < 1)
|
||||
errx(10, "-d: missing %s", name);
|
||||
argc--, argv++;
|
||||
i = atoi(*argv);
|
||||
warnx("%s changes from %dms to %dms",
|
||||
name, sblock.fs_rotdelay, i);
|
||||
sblock.fs_rotdelay = i;
|
||||
continue;
|
||||
|
||||
case 'e':
|
||||
name =
|
||||
"maximum blocks per file in a cylinder group";
|
||||
if (argc < 1)
|
||||
errx(10, "-e: missing %s", name);
|
||||
argc--, argv++;
|
||||
i = atoi(*argv);
|
||||
if (i < 1)
|
||||
errx(10, "%s must be >= 1 (was %s)",
|
||||
name, *argv);
|
||||
warnx("%s changes from %d to %d",
|
||||
name, sblock.fs_maxbpg, i);
|
||||
sblock.fs_maxbpg = i;
|
||||
continue;
|
||||
|
||||
case 'm':
|
||||
name = "minimum percentage of free space";
|
||||
if (argc < 1)
|
||||
errx(10, "-m: missing %s", name);
|
||||
argc--, argv++;
|
||||
i = atoi(*argv);
|
||||
if (i < 0 || i > 99)
|
||||
errx(10, "bad %s (%s)", name, *argv);
|
||||
warnx("%s changes from %d%% to %d%%",
|
||||
name, sblock.fs_minfree, i);
|
||||
sblock.fs_minfree = i;
|
||||
if (i >= MINFREE &&
|
||||
sblock.fs_optim == FS_OPTSPACE)
|
||||
warnx(OPTWARN, "time", ">=", MINFREE);
|
||||
if (i < MINFREE &&
|
||||
sblock.fs_optim == FS_OPTTIME)
|
||||
warnx(OPTWARN, "space", "<", MINFREE);
|
||||
continue;
|
||||
|
||||
case 'o':
|
||||
name = "optimization preference";
|
||||
if (argc < 1)
|
||||
errx(10, "-o: missing %s", name);
|
||||
argc--, argv++;
|
||||
if (strcmp(*argv, chg[FS_OPTSPACE]) == 0)
|
||||
i = FS_OPTSPACE;
|
||||
else if (strcmp(*argv, chg[FS_OPTTIME]) == 0)
|
||||
i = FS_OPTTIME;
|
||||
else
|
||||
errx(10, "bad %s (options are `space' or `time')",
|
||||
name);
|
||||
if (sblock.fs_optim == i) {
|
||||
warnx("%s remains unchanged as %s",
|
||||
name, chg[i]);
|
||||
continue;
|
||||
}
|
||||
warnx("%s changes from %s to %s",
|
||||
name, chg[sblock.fs_optim], chg[i]);
|
||||
sblock.fs_optim = i;
|
||||
if (sblock.fs_minfree >= MINFREE &&
|
||||
i == FS_OPTSPACE)
|
||||
warnx(OPTWARN, "time", ">=", MINFREE);
|
||||
if (sblock.fs_minfree < MINFREE &&
|
||||
i == FS_OPTTIME)
|
||||
warnx(OPTWARN, "space", "<", MINFREE);
|
||||
continue;
|
||||
|
||||
case 't':
|
||||
name = "track skew in sectors";
|
||||
if (argc < 1)
|
||||
errx(10, "-t: missing %s", name);
|
||||
argc--, argv++;
|
||||
i = atoi(*argv);
|
||||
if (i < 0)
|
||||
errx(10, "%s: %s must be >= 0",
|
||||
*argv, name);
|
||||
warnx("%s changes from %d to %d",
|
||||
name, sblock.fs_trackskew, i);
|
||||
sblock.fs_trackskew = i;
|
||||
continue;
|
||||
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
if (argc != 1)
|
||||
usage();
|
||||
if (Nflag) {
|
||||
fprintf(stdout, "tunefs: current settings\n");
|
||||
fprintf(stdout, "\tmaximum contiguous block count %d\n",
|
||||
sblock.fs_maxcontig);
|
||||
fprintf(stdout,
|
||||
"\trotational delay between contiguous blocks %dms\n",
|
||||
sblock.fs_rotdelay);
|
||||
fprintf(stdout,
|
||||
"\tmaximum blocks per file in a cylinder group %d\n",
|
||||
sblock.fs_maxbpg);
|
||||
fprintf(stdout, "\tminimum percentage of free space %d%%\n",
|
||||
sblock.fs_minfree);
|
||||
fprintf(stdout, "\toptimization preference: %s\n",
|
||||
chg[sblock.fs_optim]);
|
||||
fprintf(stdout, "\ttrack skew %d sectors\n",
|
||||
sblock.fs_trackskew);
|
||||
fprintf(stdout, "tunefs: no changes made\n");
|
||||
exit(0);
|
||||
}
|
||||
fi = open(special, 1);
|
||||
if (fi < 0)
|
||||
err(3, "cannot open %s for writing", special);
|
||||
bwrite((daddr_t)SBOFF / dev_bsize, (char *)&sblock, SBSIZE);
|
||||
if (Aflag)
|
||||
for (i = 0; i < sblock.fs_ncg; i++)
|
||||
bwrite(fsbtodb(&sblock, cgsblock(&sblock, i)),
|
||||
(char *)&sblock, SBSIZE);
|
||||
close(fi);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
usage()
|
||||
{
|
||||
|
||||
fprintf(stderr, "Usage: tunefs [-AN] tuneup-options special-device\n");
|
||||
fprintf(stderr, "where tuneup-options are:\n");
|
||||
fprintf(stderr, "\t-d rotational delay between contiguous blocks\n");
|
||||
fprintf(stderr, "\t-a maximum contiguous blocks\n");
|
||||
fprintf(stderr, "\t-e maximum blocks per file in a cylinder group\n");
|
||||
fprintf(stderr, "\t-m minimum percentage of free space\n");
|
||||
fprintf(stderr, "\t-o optimization preference (`space' or `time')\n");
|
||||
fprintf(stderr, "\t-t track skew in sectors\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
void
|
||||
getsb(fs, file)
|
||||
register struct fs *fs;
|
||||
char *file;
|
||||
{
|
||||
|
||||
fi = open(file, 0);
|
||||
if (fi < 0)
|
||||
err(3, "cannot open %s for reading", file);
|
||||
if (bread((daddr_t)SBOFF, (char *)fs, SBSIZE))
|
||||
err(4, "%s: bad super block", file);
|
||||
if (fs->fs_magic != FS_MAGIC)
|
||||
err(5, "%s: bad magic number", file);
|
||||
dev_bsize = fs->fs_fsize / fsbtodb(fs, 1);
|
||||
close(fi);
|
||||
}
|
||||
|
||||
void
|
||||
bwrite(blk, buf, size)
|
||||
daddr_t blk;
|
||||
char *buf;
|
||||
int size;
|
||||
{
|
||||
|
||||
if (lseek(fi, (off_t)blk * dev_bsize, SEEK_SET) < 0)
|
||||
err(6, "FS SEEK");
|
||||
if (write(fi, buf, size) != size)
|
||||
err(7, "FS WRITE");
|
||||
}
|
||||
|
||||
int
|
||||
bread(bno, buf, cnt)
|
||||
daddr_t bno;
|
||||
char *buf;
|
||||
int cnt;
|
||||
{
|
||||
int i;
|
||||
|
||||
if (lseek(fi, (off_t)bno * dev_bsize, SEEK_SET) < 0)
|
||||
return(1);
|
||||
if ((i = read(fi, buf, cnt)) != cnt) {
|
||||
for(i=0; i<sblock.fs_bsize; i++)
|
||||
buf[i] = 0;
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user