Return to BSD News archive
Newsgroups: comp.bugs.2bsd
Path: euryale.cc.adfa.oz.au!newshost.anu.edu.au!harbinger.cc.monash.edu.au!news.mel.connect.com.au!munnari.OZ.AU!spool.mu.edu!howland.reston.ans.net!newsfeed.internetmci.com!in1.uu.net!news.new-york.net!wlbr!sms
From: sms@wlv.iipo.gtegsc.com (Steven M. Schultz)
Subject: TU81 bug,statfs(2)+fstatfs(2)+getfsstat(2) missing, More (#283 1 of 4)
Sender: news@wlbr.iipo.gtegsc.com (Steven M. Schultz)
Organization: GTE Government Systems, Thousand Oaks CA USA
Message-ID: <DKAHAz.9IK@wlbr.iipo.gtegsc.com>
X-Nntp-Posting-Host: wlv.iipo.gtegsc.com
Date: Thu, 28 Dec 1995 09:06:35 GMT
Lines: 3330
Subject: TU81 bug,statfs(2)+fstatfs(2)+getfsstat(2) missing, More (#283 1 of 4)
Index: sys/pdpuba,pdp,sys 2.11BSD
Description:
The TU81 (and TU81+) drives are not handled correctly by the TMSCP
driver. Multiple files can not be created on a single tape.
The TMSCP driver does not properly check for end of media errors
which can flood the kernel logging buffer with messages if an
application persists in ignoring the initial error.
The TMSCP driver does not correctly check for or handle the caching
capability of TU81+ drives.
The 'mt(1)' program did not implement the commands necessary to
turn caching on and off.
The system calls 'statfs(2)', 'fstatfs(2)', 'getfsstat(2)' are
missing from the system.
The routine 'getmntinfo(3)' is missing from the C library.
The version of 'ping(8)' present in the system is not a newer
4.4BSD-Lite version.
A couple "standard" include files (stddef.h, stdlib.h) useful in
porting software are not present in the system.
The check by the kernel to avoid swapping to a partition unless that
partition was of type FS_SWAP was wrong.
When mounting a filesystem the kernel did not check that the
partition type was valid.
The 'fs_ilock' member of the superblock was on an ODD byte boundary.
Repeat-By:
The TMSCP bugs can easily be seen writing a file to the non-rewinding
device and then immediately trying to write a second file. An
immediate error will always result until the tape drive is rewound.
That 'fs_ilock' being incorrectly aligned has not caused a crash
(or rather no crash has been attributed to the wrong alignment)
is amazing. Evidently the locking has not been necessary YET.
The remainder of the items in 'Description:' are 'repeated' by
"observation".
Fix:
This is part 1 of 4. The four parts are:
#283 - Contains the description, installation instructions,
shell script of files to be renamed/removed, and
the shar archive of new files to be added to the
system.
#284 - The first of 3 patch files. These files are
updated:
/usr/include/syscall.h
/usr/lib/tmac/tmac.an.new
/usr/src/bin/mt.c
/usr/src/etc/Makefile
/usr/src/etc/mount.c
/usr/src/lib/libc/gen/Makefile
/usr/src/lib/libc/pdp/sys/Makefile
/usr/src/man/man1/mt.1
/usr/src/man/man2/Makefile
/usr/src/man/man3/Makefile
/usr/src/man/man4/mtio.4
/usr/src/man/man4/tmscp.4
/usr/src/man/man8/Makefile
/usr/src/sys/conf/GENERIC
/usr/src/sys/conf/Make.nsunix
/usr/src/sys/conf/Make.pdpuba
/usr/src/sys/conf/Make.sunix
/usr/src/sys/conf/Make.sys
/usr/src/sys/conf/Make.unix
#285 - The second part of the patches. These files are
updated:
/usr/src/sys/h/errno.h
/usr/src/sys/h/fs.h
/usr/src/sys/h/inode.h
/usr/src/sys/h/mount.h
/usr/src/sys/h/mtio.h
/usr/src/sys/h/param.h
/usr/src/sys/pdp/conf.c
/usr/src/sys/pdp/machdep2.c
/usr/src/sys/pdp/tmscp.h
/usr/src/sys/sys/init_main.c
/usr/src/sys/sys/init_sysent.c
/usr/src/sys/sys/syscalls.c
/usr/src/sys/sys/ufs_mount.c
/usr/src/sys/sys/ufs_syscalls.c
#286 - The third and last part of the patches. This is
also the largest patch file even though only 3 files
are being updated:
/usr/src/sys/pdpuba/tmscp.c
/usr/src/sys/pdpuba/tmscpreg.h
/VERSION
And now for the narrative of how what started out to be a "simple"
(ha!) update of the TMSCP driver turned into a 4 part monster of
a patch kit.
Note: the TU81 changes _should_ work, they've not been tested
extensively. The TMSCP driver does work at least as well as before
(and in the case of EOT detection the driver is much better). It is
anticipated there will be a small update later to the TMSCP driver.
While waiting for test time on a system with a real TU81+ I stumbled
across some listings from 1 year ago containing notes on porting
the filesystem statistics syscalls (statfs, getfsstat) and resumed
work on it.
Since ufs_syscalls.c was already large (becoming unwieldy to find
a suitable place in the overlay structure for it) a new file
'ufs_syscalls2.c' was created. Adding new modules to the kernel
means that the Make.* files in /sys/conf have to be updated and
in the case of the GENERIC config file the overlay structure has to
be corrected (this is because the GENERIC kernel is always supposed
to config+build without any changes).
Odd wakeup channels are reserved for the networking code
the kernel should NEVER sleep on an odd wakeup - if 'fs_ilock' were
ever used for sleeping then when the wakeup() was done the system
would launch itself into hyperspace (and crash shortly there after).
The fields in the superblock which were reordered are always
initialized when a filesystem is mounted.
Some time back the 4.4BSD-Lite version of 'ping' was ported (mainly to
see how hard it would be - turned out to be quite easy). The 'flood'
capability is present although a 2.11 system will not place nearly
the load on a network that a faster system would. DO NOT flood ping
_to_ a 2.11 system unless you want to kill the 2.11 system - the
mbuf pool becomes exhausted and the system becomes 'unresponsive'
(to say the least).
The TMSCP driver was the initial reason for this whole kit, and the
update to the TMSCP driver is the largest single part (accounting for
about 1/3 of the total size). Initially the hope was to reduce the
size of the driver. Alas this was not how it turned out. While
the D-space requirements were reduced slightly (hurrah!) the code
size increased dramatically. This is due to several factors: 1) The
addition of much more return status checking, 2) some additional
debug code (which can be removed by commenting out the 'TMSDEBUG'
statement at the top of tmscp.c), 3) reorganization - each function
(read, write, reposition, etc) now has its own "start" and "end"
routines. This added a fair amount of code but makes it possible
to perform function specific processing without complicated 'switch'
statements and sharing common 'case' paths.
The 4.4BSD-Lite version of 'df' was ported (mainly by ripping out
NFS related code - if anyone every implements NFS for 2.11BSD then
I'll volunteer to re-port 'df' and friends). The new version of 'df'
uses the new system calls to retrieve filesystem information and is
at least twice as fast as before (because it does not have to open
the raw device, read the superblock, and then close the device).
In sys/init_main.c the check for the swap area being of type
'FS_SWAP' was wrong. The swap device is a "BLOCK" (IFBLK) device
and not a "CHARACTER" (IFCHR) device - thus, the reference
"cdevsw[major(swapdev)]" was referring to the wrong device. For
MSCP disks the kernel was actually calling the LP driver's 'ioctl'
routine! What was needed was a routine to translate between
'block' and 'character' major device numbers. There already existed
a table in pdp/conf.c which contained the 'character' to 'block'
mapping - it was a simple matter to use the same table to provide
the reverse translation.
The 'mount' structure now has an extension structure associated
with it - this extension is external to the kernel and is mapped
in as needed. In this extension structure are kept the full pathnames
of the device being mounted (/dev/ra0g, etc) and the mount path
(/userfiles/home, etc). At present only these two items are kept
in the extension structure but in the future if the mount structure
grows the additional members can be kept external to the kernel.
In sys/ufs_mount.c code was added to check for a 'mount' being
done on the root filesystem. Previously this would have resulted
in a 'EBUSY' error (/etc/mount skipped mounting "/") because the
kernel already has mounted '/' upon boot. The changes to ufs_mount.c
check for '/' being mounted a second time and only update the
f_mntfromname field in the external mount structure extension.
When the system boots to single user state the kernel does not know
the name of the root device (/dev/ra0a) - all the kernel knows is
the major and minor device numbers (5 and 0 respectively for ra0a).
The kernel places 'root' in the 'f_mntfromname' field - when /etc/rc
does the "mount -a" then /etc/mount will mount "/" from the root device
and the kernel will update ONLY the 'f_mntfromname' field and return.
Basically it's a poor man's method of implementing MNT_UPDATE for
the specific case of the root filesystem.
Finally, the 'mount' program was modified to not skip over the
root filesystem when doing the "mount -a" (from /etc/rc). This
change combined with the modifications in ufs_mount.c causes
"/" to be entered into the /etc/mtab file. Now when you type
"mount" you will see something like:
ra0a on /
ra0c on /user
ra0e on /usr
ra0f on /xxx
instead of
ra0c on /user
ra0e on /usr
ra0f on /xxx
AND now the moment you've all been waiting for - how to install
the update kit!
1) Make sure you have all 4 parts (#283, 284, 285 and 286). The
instructions are only given in this part (#283).
Remove the mail headers from each of the four parts by cutting
where indicated and save the 4 parts to tmp files. I will refer
to the saved files as /tmp/283, /tmp/284, /tmp/285 and /tmp/286.
If you use different names then substitute as appropriate below.
2) The first part is a shar file containing two files, a shell script
and a shar file (the last 3 parts are simple patch files). Unpack
by:
cd /tmp
sh 283
3) Run the shell script:
./move.283
this renames (rather than removing) df.c, ping.c and ping.8. If
you do not want the old versions of these files then INSTEAD of
running the script above you can simply:
rm /usr/src/bin/df.c
rm /usr/src/etc/ping.c
rm /usr/src/man/man8/ping.8
4) Install the new files on the system:
sh shar.283
5) Apply the remaining patches:
patch -p0 < 284
patch -p0 < 285
patch -p0 < 286
6) Recompile the C library. While possible to recompile and
install only the new modules it is probably a better idea to
spend the extra hour to simply recompile libc.a from scratch.
cd /usr/src/lib/libc
make clean
make
make install
make clean
7) Next create the new man pages:
cd /usr/src/man/man1
/usr/man/manroff mt.1 > mt.0
install -m 444 mt.0 /usr/man/cat1
cd /usr/src/man/man2
/usr/man/manroff statfs.2 > statfs.0
/usr/man/manroff getfsstat.2 > getfsstat.0
install -m 444 statfs.0 getfsstat.0 /usr/man/cat2
ln /usr/man/cat2/statfs.0 /usr/man/cat2/fstatfs.0
cd /usr/src/man/man3
/usr/man/manroff getmntinfo.3 > getmntinfo.0
install -m 444 getmntinfo.0 /usr/man/cat3
Optionally (it can be done anytime) rebuilt the 'whatis' database:
/usr/lib/makewhatis
8) We then rebuild the updated 'mount' program:
cd /usr/src/etc
make mount
install -m 755 -s mount /etc
9) Then reconfigure and rebuild the kernel.
NOTE: The growth of the TMSCP driver and the addition of
new system calls will almost certainly require the
overlay structure to be modified.
The kernel Makefiles (Make.sys, etc) have changed. You will either
have to copy the new conf/Make.* files into each kernel build
directory OR delete your existing build directories and run
'config'. The GENERIC kernel will be used as an example below:
cd /sys
rm -r GENERIC
cd conf
./config GENERIC
cd ../GENERIC
make
then if no errors were encountered (and there should be none)
move the new generic kernel to /genunix:
mv unix /genunix
To update a kernel other than GENERIC, for example PICKLE:
cd /sys
rm -r PICKLE
cd conf
./config PICKLE
cd ../PICKLE
make
If errors about "too big for 0431" are seen then edit the 'Makefile'
to adjust the overlay layout and type "make".
make install
10) After the new kernel is installed you should reboot the system
fastboot
or, if you'd prefer to have the system perform the filesystem
checks:
reboot
11) Now that the new kernel (which understands the new system calls)
is running it is time to compile and install the new 'df'
program:
cd /usr/src/bin
make df
install -m 2755 -g operator -s df /bin/df
Try running 'df' now and see how much faster it is than before.
12) Two last programs to install and then you're all done:
cd /usr/src/etc/ping
make
make install
make clean
cd /usr/src/bin
make mt
install -m 755 -s mt /bin/mt
You're done.
Enjoy!
As always the 2.11BSD updates are available via anonymous FTP to
the system "FTP.IIPO.GTEGSC.COM" in the directory /pub/2.11BSD.
------------------------------cut here----------------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
# /tmp/move.283
# /tmp/shar.283
# This archive created: Wed Dec 27 15:01:07 1995
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f '/tmp/move.283'
then
echo shar: "will not over-write existing file '/tmp/move.283'"
else
sed 's/^Y//' << \SHAR_EOF > '/tmp/move.283'
Ymv /usr/src/bin/df.c /usr/src/bin/df.c.old
Ymv /usr/src/etc/ping.c /usr/src/etc/ping.c.old
Ymv /usr/src/man/man8/ping.8 /usr/src/man/man8/ping.8.old
SHAR_EOF
chmod 751 '/tmp/move.283'
fi
if test -f '/tmp/shar.283'
then
echo shar: "will not over-write existing file '/tmp/shar.283'"
else
sed 's/^Y//' << \SHAR_EOF > '/tmp/shar.283'
Y#! /bin/sh
Y# This is a shell archive, meaning:
Y# 1. Remove everything above the #! /bin/sh line.
Y# 2. Save the resulting text in a file.
Y# 3. Execute the file with /bin/sh (not csh) to create:
Y# /usr/include/stdlib.h
Y# /usr/src/bin/df.c
Y# /usr/src/etc/ping
Y# /usr/src/lib/libc/gen/getmntinfo.c
Y# /usr/src/man/man2/getfsstat.2
Y# /usr/src/man/man2/statfs.2
Y# /usr/src/man/man3/getmntinfo.3
Y# /usr/src/sys/h/stddef.h
Y# /usr/src/sys/pdp/mscp_common.h
Y# /usr/src/sys/pdpuba/tmscpdump.c
Y# /usr/src/sys/sys/ufs_syscalls2.c
Y# This archive created: Wed Dec 27 11:10:34 1995
Yexport PATH; PATH=/bin:/usr/bin:$PATH
Yif test -f '/usr/include/stdlib.h'
Ythen
Y echo shar: "will not over-write existing file '/usr/include/stdlib.h'"
Yelse
Ysed 's/^X//' << \SHAR_EOF > '/usr/include/stdlib.h'
YX/*-
YX * Copyright (c) 1990, 1993
YX * The Regents of the University of California. All rights reserved.
YX *
YX * Redistribution and use in source and binary forms, with or without
YX * modification, are permitted provided that the following conditions
YX * are met:
YX * 1. Redistributions of source code must retain the above copyright
YX * notice, this list of conditions and the following disclaimer.
YX * 2. Redistributions in binary form must reproduce the above copyright
YX * notice, this list of conditions and the following disclaimer in the
YX * documentation and/or other materials provided with the distribution.
YX * 3. All advertising materials mentioning features or use of this software
YX * must display the following acknowledgement:
YX * This product includes software developed by the University of
YX * California, Berkeley and its contributors.
YX * 4. Neither the name of the University nor the names of its contributors
YX * may be used to endorse or promote products derived from this software
YX * without specific prior written permission.
YX *
YX * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
YX * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
YX * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
YX * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
YX * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
YX * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
YX * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
YX * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
YX * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
YX * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
YX * SUCH DAMAGE.
YX *
YX * @(#)stdlib.h 8.3.1 (2.11BSD) 12995/12/26
YX *
YX * Adapted from the 4.4-Lite CD. The odds of a ANSI C compiler for 2.11BSD
YX * being slipped under the door are not distinguishable from 0 - so the
YX * prototypes and ANSI ifdefs have been removed from this file.
YX *
YX * Some functions (strtoul for example) do not exist yet but are retained in
YX * this file because additions to libc.a are anticipated shortly.
YX */
YX
YX#ifndef _STDLIB_H_
YX#define _STDLIB_H_
YX
YX/* #include <machine/ansi.h> */
YX
YX#ifdef notyet
YXtypedef struct {
YX int quot; /* quotient */
YX int rem; /* remainder */
YX} div_t;
YX
YXtypedef struct {
YX long quot; /* quotient */
YX long rem; /* remainder */
YX} ldiv_t;
YX#endif
YX
YX#ifndef NULL
YX#define NULL 0
YX#endif
YX
YX#define EXIT_FAILURE 1
YX#define EXIT_SUCCESS 0
YX
YX#define RAND_MAX 0x7fff
YX
YXvoid abort();
YXint abs();
YXint atexit();
YXdouble atof();
YXint atoi();
YXlong atol();
YXvoid *calloc();
YXvoid exit();
YXvoid free();
YXchar *getenv();
YXvoid *malloc();
YXvoid qsort();
YXint rand();
YXvoid *realloc();
YXvoid srand();
YXdouble strtod();
YXlong strtol();
YXunsigned long strtoul();
YXint system();
YX
YXint putenv();
YXint setenv();
YX
YXvoid *alloca();
YX
YXint daemon();
YXchar *devname();
YXint getloadavg();
YX
YXextern char *optarg; /* getopt(3) external variables */
YXextern int opterr, optind, optopt;
YXint getopt();
YX
YX#ifdef notyet
YXextern char *suboptarg; /* getsubopt(3) external variable */
YXint getsubopt();
YX#endif
YX
YXlong random();
YXchar *setstate();
YXvoid srandom();
YXvoid unsetenv();
YX
YX#endif /* _STDLIB_H_ */
YSHAR_EOF
Ychmod 444 '/usr/include/stdlib.h'
Yfi
Yif test -f '/usr/src/bin/df.c'
Ythen
Y echo shar: "will not over-write existing file '/usr/src/bin/df.c'"
Yelse
Ysed 's/^X//' << \SHAR_EOF > '/usr/src/bin/df.c'
YX/*
YX * Copyright (c) 1980, 1990, 1993, 1994
YX * The Regents of the University of California. All rights reserved.
YX * (c) UNIX System Laboratories, Inc.
YX * All or some portions of this file are derived from material licensed
YX * to the University of California by American Telephone and Telegraph
YX * Co. or Unix System Laboratories, Inc. and are reproduced herein with
YX * the permission of UNIX System Laboratories, Inc.
YX *
YX * Redistribution and use in source and binary forms, with or without
YX * modification, are permitted provided that the following conditions
YX * are met:
YX * 1. Redistributions of source code must retain the above copyright
YX * notice, this list of conditions and the following disclaimer.
YX * 2. Redistributions in binary form must reproduce the above copyright
YX * notice, this list of conditions and the following disclaimer in the
YX * documentation and/or other materials provided with the distribution.
YX * 3. All advertising materials mentioning features or use of this software
YX * must display the following acknowledgement:
YX * This product includes software developed by the University of
YX * California, Berkeley and its contributors.
YX * 4. Neither the name of the University nor the names of its contributors
YX * may be used to endorse or promote products derived from this software
YX * without specific prior written permission.
YX *
YX * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
YX * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
YX * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
YX * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
YX * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
YX * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
YX * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
YX * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
YX * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
YX * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
YX * SUCH DAMAGE.
YX */
YX
YX#if !defined(lint) && defined(DOSCCS)
YXstatic char copyright[] =
YX"@(#) Copyright (c) 1980, 1990, 1993, 1994\n\
YX The Regents of the University of California. All rights reserved.\n";
YX
YXstatic char sccsid[] = "@(#)df.c 8.7.1 (2.11BSD) 1995/12/26";
YX#endif
YX
YX#include <sys/param.h>
YX#include <sys/stat.h>
YX#include <sys/mount.h>
YX#include <sys/file.h>
YX
YX#include <errno.h>
YX#include <fcntl.h>
YX#include <stdio.h>
YX#include <stdlib.h>
YX#include <string.h>
YX
YXint bread();
YXchar *getmntpt();
YXvoid prtstat();
YXvoid ufs_df();
YXvoid usage();
YX
YXint iflag;
YX
YXint
YXmain(argc, argv)
YX int argc;
YX register char *argv[];
YX{
YX struct stat stbuf;
YX struct statfs statfsbuf, *mntbuf;
YX int mntsize;
YX int ch, err, i, maxwidth, width;
YX char *mntpt;
YX
YX while ((ch = getopt(argc, argv, "i")) != EOF)
YX switch (ch) {
YX case 'i':
YX iflag = 1;
YX break;
YX case '?':
YX default:
YX usage();
YX }
YX argc -= optind;
YX argv += optind;
YX
YX mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
YX maxwidth = 0;
YX for (i = 0; i < mntsize; i++) {
YX width = strlen(mntbuf[i].f_mntfromname);
YX if (width > maxwidth)
YX maxwidth = width;
YX }
YX
YX if (!*argv) {
YX for (i = 0; i < mntsize; i++)
YX prtstat(&mntbuf[i], maxwidth);
YX exit(0);
YX }
YX
YX for (; *argv; argv++) {
YX if (stat(*argv, &stbuf) < 0) {
YX err = errno;
YX if ((mntpt = getmntpt(*argv)) == 0) {
YX warn("%s", *argv);
YX continue;
YX }
YX } else if ((stbuf.st_mode & S_IFMT) == S_IFCHR) {
YX ufs_df(*argv, maxwidth);
YX continue;
YX } else if ((stbuf.st_mode & S_IFMT) == S_IFBLK) {
YX if ((mntpt = getmntpt(*argv)) == 0) {
YX ufs_df(*argv, maxwidth);
YX continue;
YX }
YX } else
YX mntpt = *argv;
YX /*
YX * Statfs does not take a `wait' flag, so we cannot
YX * implement nflag here.
YX */
YX if (statfs(mntpt, &statfsbuf) < 0) {
YX warn("%s", mntpt);
YX continue;
YX }
YX if (argc == 1)
YX maxwidth = strlen(statfsbuf.f_mntfromname) + 1;
YX prtstat(&statfsbuf, maxwidth);
YX }
YX return (0);
YX}
YX
YXchar *
YXgetmntpt(name)
YX char *name;
YX{
YX register int i;
YX int mntsize;
YX struct statfs *mntbuf;
YX
YX mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
YX for (i = 0; i < mntsize; i++) {
YX if (!strcmp(mntbuf[i].f_mntfromname, name))
YX return (mntbuf[i].f_mntonname);
YX }
YX return (0);
YX}
YX
YX/*
YX * Convert statfs returned filesystem size into BLOCKSIZE units.
YX * Attempts to avoid overflow for large filesystems.
YX */
YXlong
YXfsbtoblk(num, fsbs, bs)
YX long num;
YX register int fsbs, bs;
YX {
YX return((fsbs != 0 && fsbs < bs) ?
YX num / (bs / fsbs) : (num) * (fsbs / bs));
YX }
YX
YX/*
YX * Print out status about a filesystem.
YX */
YXvoid
YXprtstat(sfsp, maxwidth)
YX register struct statfs *sfsp;
YX register int maxwidth;
YX{
YX static int blocksize;
YX static int headerlen, timesthrough;
YX static char *header;
YX long used, availblks;
YX ino_t inodes, iused;
YX
YX if (maxwidth < 11)
YX maxwidth = 11;
YX if (++timesthrough == 1) {
YX/* header = getbsize(&headerlen, &blocksize); */
YX header = "1K-blocks";
YX blocksize = 1024;
YX headerlen = 9;
YX
YX (void)printf("%-*.*s %s Used Avail Capacity",
YX maxwidth, maxwidth, "Filesystem", header);
YX if (iflag)
YX (void)printf(" iused ifree %%iused");
YX (void)printf(" Mounted on\n");
YX }
YX (void)printf("%-*.*s", maxwidth, maxwidth, sfsp->f_mntfromname);
YX used = sfsp->f_blocks - sfsp->f_bfree;
YX availblks = sfsp->f_bavail + used;
YX (void)printf(" %*ld %8ld %8ld", headerlen,
YX fsbtoblk(sfsp->f_blocks, sfsp->f_bsize, blocksize),
YX fsbtoblk(used, sfsp->f_bsize, blocksize),
YX fsbtoblk(sfsp->f_bavail, sfsp->f_bsize, blocksize));
YX (void)printf(" %5.0f%%",
YX availblks == 0 ? 100.0 : (double)used / (double)availblks * 100.0);
YX if (iflag) {
YX inodes = sfsp->f_files;
YX iused = inodes - sfsp->f_ffree;
YX (void)printf(" %7u %7u %5.0f%% ", iused, sfsp->f_ffree,
YX inodes == 0 ? 100.0 : (double)iused / (double)inodes * 100.0);
YX } else
YX (void)printf(" ");
YX (void)printf(" %s\n", sfsp->f_mntonname);
YX}
YX
YX/*
YX * This code constitutes the pre-system call Berkeley df code for extracting
YX * information from filesystem superblocks.
YX */
YX#include <sys/fs.h>
YX#include <fstab.h>
YX
YXunion {
YX struct fs fs;
YX char dummy[SBSIZE];
YX} sb;
YX#define sblock sb.fs
YX
YXint rfd;
YX
YXvoid
YXufs_df(file, maxwidth)
YX char *file;
YX int maxwidth;
YX{
YX struct statfs statfsbuf;
YX register struct statfs *sfsp;
YX register char *mntpt;
YX static int synced;
YX
YX if (synced++ == 0)
YX sync();
YX
YX if ((rfd = open(file, O_RDONLY)) < 0) {
YX warn("%s", file);
YX return;
YX }
YX if (bread((off_t)SBLOCK * DEV_BSIZE, &sblock, SBSIZE) == 0) {
YX (void)close(rfd);
YX return;
YX }
YX sfsp = &statfsbuf;
YX sfsp->f_type = MOUNT_UFS;
YX sfsp->f_flags = 0;
YX sfsp->f_bsize = MAXBSIZE;
YX sfsp->f_iosize = MAXBSIZE;
YX sfsp->f_blocks = sblock.fs_fsize;
YX sfsp->f_bfree = sblock.fs_tfree;
YX sfsp->f_bavail = sblock.fs_tfree;
YX if (sfsp->f_bavail < 0)
YX sfsp->f_bavail = 0;
YX sfsp->f_files = (sblock.fs_isize - 2) * INOPB;
YX sfsp->f_ffree = sblock.fs_tinode;
YX sfsp->f_fsid[0] = 0;
YX sfsp->f_fsid[1] = 0;
YX if ((mntpt = getmntpt(file)) == 0)
YX mntpt = "";
YX bcopy(mntpt, &sfsp->f_mntonname[0], MNAMELEN);
YX bcopy(file, &sfsp->f_mntfromname[0], MNAMELEN);
YX prtstat(sfsp, maxwidth);
YX (void)close(rfd);
YX}
YX
YXint
YXbread(off, buf, cnt)
YX off_t off;
YX void *buf;
YX register int cnt;
YX{
YX register int nr;
YX
YX (void)lseek(rfd, off, L_SET);
YX if ((nr = read(rfd, buf, cnt)) != cnt) {
YX /* Probably a dismounted disk if errno == EIO. */
YX if (errno != EIO)
YX (void)fprintf(stderr, "\ndf: %ld: %s\n",
YX off, strerror(nr > 0 ? EIO : errno));
YX return (0);
YX }
YX return (1);
YX}
YX
YXvoid
YXusage()
YX{
YX (void)fprintf(stderr, "usage: df [-i] [file | file_system ...]\n");
YX exit(1);
YX}
YSHAR_EOF
Ychmod 644 '/usr/src/bin/df.c'
Yfi
Yif test ! -d '/usr/src/etc/ping'
Ythen
Y mkdir '/usr/src/etc/ping'
Yfi
Ycd '/usr/src/etc/ping'
Yif test -f 'Makefile'
Ythen
Y echo shar: "will not over-write existing file 'Makefile'"
Yelse
Ysed 's/^X//' << \SHAR_EOF > 'Makefile'
YX#
YX# @(#)Makefile 1.0 (2.11BSD) 1995/12/22
YX#
YX
YXCFLAGS= -O
YXSEPFLAG= -i
YXLIBC= /lib/libc.a
YXSRCS= ping.c
YXOBJS= ping.o
YXMAN= ping.0
YXMANSRC= ping.8
YX
YXall: ping ${MAN}
YX
YXping: ${LIBC}
YX ${CC} ${SEPFLAG} -o $@ ${CFLAGS} $@.c
YX
YXping.0: ${MANSRC}
YX /usr/man/manroff ${MANSRC} > ${MAN}
YX
YXclean:
YX rm -f ${OBJS} ${MAN} ping
YX
YXcleandir: clean
YX rm -f tags .depend
YX
YXdepend: ${SRCS}
YX mkdep -p ${CFLAGS} ${SRCS}
YX
YXinstall: ${MAN} ping
YX install -s -o root -g bin -m 4751 ping ${DESTDIR}/etc
YX install -c -o bin -g bin -m 444 ${MAN} ${DESTDIR}/usr/man/cat8
YX
YXlint: ${SRCS}
YX lint -haxc ${SRCS}
YX
YXtags: ${SRCS}
YX ctags ${SRCS}
YSHAR_EOF
Ychmod 644 'Makefile'
Yfi
Yif test -f 'ping.8'
Ythen
Y echo shar: "will not over-write existing file 'ping.8'"
Yelse
Ysed 's/^X//' << \SHAR_EOF > 'ping.8'
YX.\" Copyright (c) 1985, 1991, 1993
YX.\" The Regents of the University of California. All rights reserved.
YX.\"
YX.\" Redistribution and use in source and binary forms, with or without
YX.\" modification, are permitted provided that the following conditions
YX.\" are met:
YX.\" 1. Redistributions of source code must retain the above copyright
YX.\" notice, this list of conditions and the following disclaimer.
YX.\" 2. Redistributions in binary form must reproduce the above copyright
YX.\" notice, this list of conditions and the following disclaimer in the
YX.\" documentation and/or other materials provided with the distribution.
YX.\" 3. All advertising materials mentioning features or use of this software
YX.\" must display the following acknowledgement:
YX.\" This product includes software developed by the University of
YX.\" California, Berkeley and its contributors.
YX.\" 4. Neither the name of the University nor the names of its contributors
YX.\" may be used to endorse or promote products derived from this software
YX.\" without specific prior written permission.
YX.\"
YX.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
YX.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
YX.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
YX.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
YX.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
YX.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
YX.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
YX.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
YX.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
YX.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
YX.\" SUCH DAMAGE.
YX.\"
YX.\" @(#)ping.8 8.2.1 (2.11BSD) 1995/12/22
YX.\"
YX.TH PING 8 "December 22, 1995"
YX.AT 3
YX.SH NAME
YX\fBping\fP \- send ICMP ECHO_REQUEST packets to network hosts
YX.SH SYNOPSIS
YX.B ping [-dfnqrvR]
YX[\fB-c\fP \fIcount\fP]
YX[\fB-i\fP \fIwait\fP]
YX[\fB-l\fP \fIpreload\fP]
YX[\fB-p\fP \fIpattern\fP]
YX[\fB-s\fP \fIpacketsize\fP]
YX.SH DESCRIPTION
YX.B Ping
YXuses the
YXICMP
YXprotocol's mandatory
YXECHO_REQUEST
YXdatagram to elicit an
YXICMP ECHO_RESPONSE
YXfrom a host or gateway.
YXECHO_REQUEST
YXdatagrams (``pings'') have an IP and
YXICMP
YXheader,
YXfollowed by a
YX``struct timeval''
YXand then an arbitrary number of ``pad'' bytes used to fill out the
YXpacket.
YXThe options are as follows:
YX.TP 15
YX\fB-c\fP \fIcount\fP
YXStop after sending (and receiving)
YX.I count
YXECHO_RESPONSE
YXpackets.
YX.TP 15
YX\fB-d\fP
YXSet the
YXSO_DEBUG
YXoption on the socket being used.
YX.TP 15
YX\fB-f\fP
YXFlood ping.
YXOutputs packets as fast as they come back or one hundred times per second,
YXwhichever is more.
YXFor every
YXECHO_REQUEST
YXsent a period ``.'' is printed, while for every
YXECHO_REPLY
YXreceived a backspace is printed.
YXThis provides a rapid display of how many packets are being dropped.
YXOnly the super-user may use this option.
YX.B This can be very hard on a network and should be used with caution.
YX.TP 15
YX\fB-i\fP \fIwait\fP
YXWait
YX.I wait
YXseconds
YXbetween sending each packet.
YXThe default is to wait for one second between each packet.
YXThis option is incompatible with the
YX\fB-f\fP
YXoption.
YX.TP 15
YX\fB-l\fP \fIpreload\fP
YXIf
YX.I preload
YXis specified,
YX.B ping
YXsends that many packets as fast as possible before falling into its normal
YXmode of behavior.
YX.TP 15
YX\fB-n\fP
YXNumeric output only.
YXNo attempt will be made to lookup symbolic names for host addresses.
YX.TP 15
YX\fB-p\fP \fIpattern\fP
YXYou may specify up to 16 ``pad'' bytes to fill out the packet you send.
YXThis is useful for diagnosing data-dependent problems in a network.
YXFor example,
YX`` \-p ff''
YXwill cause the sent packet to be filled with all
YXones.
YX.TP 15
YX\fB-q\fP
YXQuiet output.
YXNothing is displayed except the summary lines at startup time and
YXwhen finished.
YX.TP 15
YX\fB-R\fP
YXRecord route.
YXIncludes the
YXRECORD_ROUTE
YXoption in the
YXECHO_REQUEST
YXpacket and displays
YXthe route buffer on returned packets.
YXNote that the IP header is only large enough for nine such routes.
YXMany hosts ignore or discard this option.
YX.TP 15
YX\fB-r\fP
YXBypass the normal routing tables and send directly to a host on an attached
YXnetwork.
YXIf the host is not on a directly-attached network, an error is returned.
YXThis option can be used to ping a local host through an interface
YXthat has no route through it (e.g., after the interface was dropped by
YX.BR routed (8).
YX.TP 15
YX\fB-s\fP \fIpacketsize\fP
YXSpecifies the number of data bytes to be sent.
YXThe default is 56, which translates into 64
YXICMP
YXdata bytes when combined
YXwith the 8 bytes of
YXICMP
YXheader data.
YX.TP 15
YX\fB-v\fP
YXVerbose output.
YXICMP
YXpackets other than
YXECHO_RESPONSE
YXthat are received are listed.
YX.PP
YXWhen using
YX.B ping
YXfor fault isolation, it should first be run on the local host, to verify
YXthat the local network interface is up and running.
YXThen, hosts and gateways further and further away should be ``pinged''.
YXRound-trip times and packet loss statistics are computed.
YXIf duplicate packets are received, they are not included in the packet
YXloss calculation, although the round trip time of these packets is used
YXin calculating the minimum/average/maximum round-trip time numbers.
YXWhen the specified number of packets have been sent (and received) or
YXif the program is terminated with a
YXSIGINT,
YXa brief summary is displayed.
YX.PP
YXThis program is intended for use in network testing, measurement and
YXmanagement.
YXBecause of the load it can impose on the network, it is unwise to use
YX.B ping
YXduring normal operations or from automated scripts.
YX.SH ICMP PACKET DETAILS
YXAn IP header without options is 20 bytes.
YXAn
YXICMP
YXECHO_REQUEST
YXpacket contains an additional 8 bytes worth
YXof
YXICMP
YXheader followed by an arbitrary amount of data.
YXWhen a
YX.I packetsize
YXis given, this indicated the size of this extra piece of data (the
YXdefault is 56).
YXThus the amount of data received inside of an IP packet of type
YXICMP
YXECHO_REPLY
YXwill always be 8 bytes more than the requested data space
YX(the
YXICMP
YXheader).
YX.PP
YXIf the data space is at least eight bytes large,
YX.B ping
YXuses the first eight bytes of this space to include a timestamp which
YXit uses in the computation of round trip times.
YXIf less than eight bytes of pad are specified, no round trip times are
YXgiven.
YX.SH DUPLICATE AND DAMAGED PACKETS
YX.B Ping
YXwill report duplicate and damaged packets.
YXDuplicate packets should never occur, and seem to be caused by
YXinappropriate link-level retransmissions.
YXDuplicates may occur in many situations and are rarely (if ever) a
YXgood sign, although the presence of low levels of duplicates may not
YXalways be cause for alarm.
YX.PP
YXDamaged packets are obviously serious cause for alarm and often
YXindicate broken hardware somewhere in the
YX.B ping
YXpacket's path (in the network or in the hosts).
YX.SH TRYING DIFFERENT DATA PATTERNS
YXThe (inter)network layer should never treat packets differently depending
YXon the data contained in the data portion.
YXUnfortunately, data-dependent problems have been known to sneak into
YXnetworks and remain undetected for long periods of time.
YXIn many cases the particular pattern that will have problems is something
YXthat doesn't have sufficient ``transitions'', such as all ones or all
YXzeros, or a pattern right at the edge, such as almost all zeros.
YXIt isn't necessarily enough to specify a data pattern of all zeros (for
YXexample) on the command line because the pattern that is of interest is
YXat the data link level, and the relationship between what you type and
YXwhat the controllers transmit can be complicated.
YX.PP
YXThis means that if you have a data-dependent problem you will probably
YXhave to do a lot of testing to find it.
YXIf you are lucky, you may manage to find a file that either can't be sent
YXacross your network or that takes much longer to transfer than other
YXsimilar length files.
YXYou can then examine this file for repeated patterns that you can test
YXusing the
YX\fB-p\fP
YXoption of
YX.BR ping .
YX.SH TTL DETAILS
YXThe
YXTTL
YXvalue of an IP packet represents the maximum number of IP routers
YXthat the packet can go through before being thrown away.
YXIn current practice you can expect each router in the Internet to decrement
YXthe
YXTTL
YXfield by exactly one.
YX.PP
YXThe
YXTCP/IP
YXspecification states that the
YXTTL
YXfield for
YXTCP
YXpackets should
YXbe set to 60, but many systems use smaller values (4.3BSD
YXuses 30, 4.2 used
YX15).
YX.PP
YXThe maximum possible value of this field is 255, and most Unix systems set
YXthe
YXTTL
YXfield of
YXICMP ECHO_REQUEST
YXpackets to 255.
YXThis is why you will find you can ``ping'' some hosts, but not reach them
YXwith
YX.BR telnet (1)
YXor
YX.BR ftp (1) .
YX.PP
YXIn normal operation ping prints the ttl value from the packet it receives.
YXWhen a remote system receives a ping packet, it can do one of three things
YXwith the
YXTTL
YXfield in its response:
YX.TP 5
YX\(bu
YXNot change it; this is what Berkeley Unix systems did before the
YX4.3BSD-tahoe
YXrelease.
YXIn this case the
YXTTL
YXvalue in the received packet will be 255 minus the
YXnumber of routers in the round-trip path.
YX.TP 5
YX\(bu
YXSet it to 255; this is what current Berkeley Unix systems do.
YXIn this case the
YXTTL
YXvalue in the received packet will be 255 minus the
YXnumber of routers in the path
YX.B from
YXthe remote system
YX.I to
YXthe
YX\fBping\fP'ing
YXhost.
YX.TP 5
YX\(bu
YXSet it to some other value.
YXSome machines use the same value for
YXICMP
YXpackets that they use for
YXTCP
YXpackets, for example either 30 or 60.
YXOthers may use completely wild values.
YX.SH BUGS
YXMany Hosts and Gateways ignore the
YXRECORD_ROUTE
YXoption.
YX.PP
YXThe maximum IP header length is too small for options like
YXRECORD_ROUTE
YXto
YXbe completely useful.
YXThere's not much that that can be done about this, however.
YX.PP
YXFlood pinging is not recommended in general, and flood pinging the
YXbroadcast address should only be done under very controlled conditions.
YX.SH SEE ALSO
YX.BR netstat (1),
YX.BR ifconfig (8),
YX.BR routed (8)
YX.SH HISTORY
YXThe
YX.B ping
YXcommand appeared in
YX4.3BSD.
YSHAR_EOF
Ychmod 644 'ping.8'
Yfi
Yif test -f 'ping.c'
Ythen
Y echo shar: "will not over-write existing file 'ping.c'"
Yelse
Ysed 's/^X//' << \SHAR_EOF > 'ping.c'
YX/* BSDI ping.c,v 2.1 1995/02/03 07:30:55 polk Exp */
YX
YX/*
YX * Copyright (c) 1989, 1993
YX * The Regents of the University of California. All rights reserved.
YX *
YX * This code is derived from software contributed to Berkeley by
YX * Mike Muuss.
YX *
YX * Redistribution and use in source and binary forms, with or without
YX * modification, are permitted provided that the following conditions
YX * are met:
YX * 1. Redistributions of source code must retain the above copyright
YX * notice, this list of conditions and the following disclaimer.
YX * 2. Redistributions in binary form must reproduce the above copyright
YX * notice, this list of conditions and the following disclaimer in the
YX * documentation and/or other materials provided with the distribution.
YX * 3. All advertising materials mentioning features or use of this software
YX * must display the following acknowledgement:
YX * This product includes software developed by the University of
YX * California, Berkeley and its contributors.
YX * 4. Neither the name of the University nor the names of its contributors
YX * may be used to endorse or promote products derived from this software
YX * without specific prior written permission.
YX *
YX * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
YX * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
YX * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
YX * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
YX * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
YX * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
YX * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
YX * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
YX * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
YX * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
YX * SUCH DAMAGE.
YX */
YX
YX#if !defined(lint) && defined(DOSCCS)
YXstatic char copyright[] =
YX"@(#) Copyright (c) 1989, 1993\n\
YX The Regents of the University of California. All rights reserved.\n";
YX
YXstatic char sccsid[] = "@(#)ping.c 8.1 (Berkeley) 6/5/93";
YX#endif /* not lint */
YX
YX/*
YX * P I N G . C
YX *
YX * Using the InterNet Control Message Protocol (ICMP) "ECHO" facility,
YX * measure round-trip-delays and packet loss across network paths.
YX *
YX * Author -
YX * Mike Muuss
YX * U. S. Army Ballistic Research Laboratory
YX * December, 1983
YX *
YX * Status -
YX * Public Domain. Distribution Unlimited.
YX * Bugs -
YX * More statistics could always be gathered.
YX * This program has to run SUID to ROOT to access the ICMP socket.
YX */
YX
YX#include <sys/param.h>
YX#include <sys/socket.h>
YX#include <sys/file.h>
YX#include <sys/time.h>
YX#include <sys/signal.h>
YX
YX#include <netinet/in_systm.h>
YX#include <netinet/in.h>
YX#include <netinet/ip.h>
YX#include <netinet/ip_icmp.h>
YX#include <netinet/ip_var.h>
YX#include <netdb.h>
YX#include <stdio.h>
YX#include <ctype.h>
YX#include <errno.h>
YX#include <string.h>
YX
YX#define DEFDATALEN (64 - 8) /* default data length */
YX#define MAXIPLEN 60
YX#define MAXICMPLEN 76
YX#define MAXPACKET (4096 - 60 - 8) /* max packet size */
YX#define MAXWAIT 10 /* max seconds to wait for response */
YX#define NROUTES 9 /* number of record route slots */
YX
YX#define A(bit) rcvd_tbl[(bit)>>3] /* identify byte in array */
YX#define B(bit) (1 << ((bit) & 0x07)) /* identify bit in byte */
YX#define SET(bit) (A(bit) |= B(bit))
YX#define CLR(bit) (A(bit) &= (~B(bit)))
YX#define TST(bit) (A(bit) & B(bit))
YX
YX/* various options */
YXint options;
YX#define F_FLOOD 0x001
YX#define F_INTERVAL 0x002
YX#define F_NUMERIC 0x004
YX#define F_PINGFILLED 0x008
YX#define F_QUIET 0x010
YX#define F_RROUTE 0x020
YX#define F_SO_DEBUG 0x040
YX#define F_SO_DONTROUTE 0x080
YX#define F_VERBOSE 0x100
YX
YX/*
YX * MAX_DUP_CHK is the number of bits in received table, i.e. the maximum
YX * number of received sequence numbers we can keep track of. Change 512
YX * to 8192 for complete accuracy...
YX */
YX#define MAX_DUP_CHK (8 * 512)
YXint mx_dup_ck = MAX_DUP_CHK;
YXchar rcvd_tbl[MAX_DUP_CHK / 8];
YX
YXstruct sockaddr whereto; /* who to ping */
YXint datalen = DEFDATALEN;
YXint s; /* socket file descriptor */
YXu_char outpack[MAXPACKET];
YXchar BSPACE = '\b'; /* characters written for flood */
YXchar DOT = '.';
YXchar *hostname;
YXint ident; /* process id to identify our packets */
YX
YX/* counters */
YXlong npackets; /* max packets to transmit */
YXlong nreceived; /* # of packets we got back */
YXlong nrepeats; /* number of duplicates */
YXlong ntransmitted; /* sequence # for outbound packets = #sent */
YXint interval = 1; /* interval between packets */
YX
YX/* timing */
YXint timing; /* flag to do timing */
YXdouble tmin = 999999999.0; /* minimum round trip time */
YXdouble tmax = 0.0; /* maximum round trip time */
YXdouble tsum = 0.0; /* sum of all times, for doing average */
YX
YXchar *pr_addr();
YXvoid catcher(), finish();
YX
YXmain(argc, argv)
YX int argc;
YX char **argv;
YX{
YX extern int errno, optind;
YX extern char *optarg;
YX struct timeval timeout;
YX struct hostent *hp;
YX struct sockaddr_in *to;
YX struct protoent *proto;
YX register int i;
YX int ch, fdmask, hold, packlen, preload;
YX u_char *datap, *packet;
YX char *target, hnamebuf[MAXHOSTNAMELEN], *malloc();
YX#ifdef IP_OPTIONS
YX char rspace[3 + 4 * NROUTES + 1]; /* record route space */
YX#endif
YX
YX preload = 0;
YX datap = &outpack[8 + sizeof(struct timeval)];
YX while ((ch = getopt(argc, argv, "Rc:dfh:i:l:np:qrs:v")) != EOF)
YX switch(ch) {
YX case 'c':
YX npackets = atoi(optarg);
YX if (npackets <= 0) {
YX (void)fprintf(stderr,
YX "ping: bad number of packets to transmit.\n");
YX exit(1);
YX }
YX break;
YX case 'd':
YX options |= F_SO_DEBUG;
YX break;
YX case 'f':
YX if (getuid()) {
YX (void)fprintf(stderr,
YX "ping: %s\n", strerror(EPERM));
YX exit(1);
YX }
YX options |= F_FLOOD;
YX setbuf(stdout, (char *)NULL);
YX break;
YX case 'i': /* wait between sending packets */
YX interval = atoi(optarg);
YX if (interval <= 0) {
YX (void)fprintf(stderr,
YX "ping: bad timing interval.\n");
YX exit(1);
YX }
YX options |= F_INTERVAL;
YX break;
YX case 'l':
YX preload = atoi(optarg);
YX if (preload < 0) {
YX (void)fprintf(stderr,
YX "ping: bad preload value.\n");
YX exit(1);
YX }
YX break;
YX case 'n':
YX options |= F_NUMERIC;
YX break;
YX case 'p': /* fill buffer with user pattern */
YX options |= F_PINGFILLED;
YX fill((char *)datap, optarg);
YX break;
YX case 'q':
YX options |= F_QUIET;
YX break;
YX case 'R':
YX options |= F_RROUTE;
YX break;
YX case 'r':
YX options |= F_SO_DONTROUTE;
YX break;
YX case 's': /* size of packet to send */
YX datalen = atoi(optarg);
YX if (datalen > MAXPACKET) {
YX (void)fprintf(stderr,
YX "ping: packet size too large.\n");
YX exit(1);
YX }
YX if (datalen <= 0) {
YX (void)fprintf(stderr,
YX "ping: illegal packet size.\n");
YX exit(1);
YX }
YX break;
YX case 'v':
YX options |= F_VERBOSE;
YX break;
YX default:
YX usage();
YX }
YX argc -= optind;
YX argv += optind;
YX
YX if (argc != 1)
YX usage();
YX target = *argv;
YX
YX bzero((char *)&whereto, sizeof(struct sockaddr));
YX to = (struct sockaddr_in *)&whereto;
YX to->sin_family = AF_INET;
YX to->sin_addr.s_addr = inet_addr(target);
YX if (to->sin_addr.s_addr != -1L)
YX hostname = target;
YX else {
YX hp = gethostbyname(target);
YX if (!hp) {
YX (void)fprintf(stderr,
YX "ping: unknown host %s\n", target);
YX exit(1);
YX }
YX to->sin_family = hp->h_addrtype;
YX bcopy(hp->h_addr, (caddr_t)&to->sin_addr, hp->h_length);
YX (void)strncpy(hnamebuf, hp->h_name, sizeof(hnamebuf) - 1);
YX hostname = hnamebuf;
YX }
YX
YX if (options & F_FLOOD && options & F_INTERVAL) {
YX (void)fprintf(stderr,
YX "ping: -f and -i incompatible options.\n");
YX exit(1);
YX }
YX
YX if (datalen >= sizeof(struct timeval)) /* can we time transfer */
YX timing = 1;
YX packlen = datalen + MAXIPLEN + MAXICMPLEN;
YX if (!(packet = (u_char *)malloc((u_int)packlen))) {
YX (void)fprintf(stderr, "ping: out of memory.\n");
YX exit(1);
YX }
YX if (!(options & F_PINGFILLED))
YX for (i = 8; i < datalen; ++i)
YX *datap++ = i;
YX
YX ident = getpid() & 0xFFFF;
YX
YX if (!(proto = getprotobyname("icmp"))) {
YX (void)fprintf(stderr, "ping: unknown protocol icmp.\n");
YX exit(1);
YX }
YX if ((s = socket(AF_INET, SOCK_RAW, proto->p_proto)) < 0) {
YX perror("ping: socket");
YX exit(1);
YX }
YX hold = 1;
YX if (options & F_SO_DEBUG)
YX (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&hold,
YX sizeof(hold));
YX if (options & F_SO_DONTROUTE)
YX (void)setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&hold,
YX sizeof(hold));
YX
YX /* record route option */
YX if (options & F_RROUTE) {
YX#ifdef IP_OPTIONS
YX rspace[IPOPT_OPTVAL] = IPOPT_RR;
YX rspace[IPOPT_OLEN] = sizeof(rspace)-1;
YX rspace[IPOPT_OFFSET] = IPOPT_MINOFF;
YX if (setsockopt(s, IPPROTO_IP, IP_OPTIONS, rspace,
YX sizeof(rspace)) < 0) {
YX perror("ping: record route");
YX exit(1);
YX }
YX#else
YX (void)fprintf(stderr,
YX "ping: record route not available in this implementation.\n");
YX exit(1);
YX#endif /* IP_OPTIONS */
YX }
YX
YX /*
YX * When pinging the broadcast address, you can get a lot of answers.
YX * Doing something so evil is useful if you are trying to stress the
YX * ethernet, or just want to fill the arp cache to get some stuff for
YX * /etc/ethers.
YX */
YX hold = 48 * 1024;
YX (void)setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&hold,
YX sizeof(hold));
YX
YX if (to->sin_family == AF_INET)
YX (void)printf("PING %s (%s): %d data bytes\n", hostname,
YX inet_ntoa(*(struct in_addr *)&to->sin_addr.s_addr),
YX datalen);
YX else
YX (void)printf("PING %s: %d data bytes\n", hostname, datalen);
YX
YX (void)signal(SIGINT, finish);
YX (void)signal(SIGALRM, catcher);
YX
YX while (preload--) /* fire off them quickies */
YX pinger();
YX
YX if ((options & F_FLOOD) == 0)
YX catcher(); /* start things going */
YX
YX for (;;) {
YX struct sockaddr_in from;
YX register int cc;
YX int fromlen;
YX
YX if (options & F_FLOOD) {
YX pinger();
YX timeout.tv_sec = 0;
YX timeout.tv_usec = 10000;
YX fdmask = 1 << s;
YX if (select(s + 1, (fd_set *)&fdmask, (fd_set *)NULL,
YX (fd_set *)NULL, &timeout) < 1)
YX continue;
YX }
YX fromlen = sizeof(from);
YX if ((cc = recvfrom(s, (char *)packet, packlen, 0,
YX (struct sockaddr *)&from, &fromlen)) < 0) {
YX if (errno == EINTR)
YX continue;
YX perror("ping: recvfrom");
YX continue;
YX }
YX pr_pack((char *)packet, cc, &from);
YX if (npackets && nreceived >= npackets)
YX break;
YX }
YX finish();
YX /* NOTREACHED */
YX}
YX
YX/*
YX * catcher --
YX * This routine causes another PING to be transmitted, and then
YX * schedules another SIGALRM for 1 second from now.
YX *
YX * bug --
YX * Our sense of time will slowly skew (i.e., packets will not be
YX * launched exactly at 1-second intervals). This does not affect the
YX * quality of the delay and loss statistics.
YX */
YXvoid
YXcatcher()
YX{
YX int waittime;
YX
YX pinger();
YX (void)signal(SIGALRM, catcher);
YX if (!npackets || ntransmitted < npackets)
YX alarm((u_int)interval);
YX else {
YX if (nreceived) {
YX waittime = 2 * tmax / 1000;
YX if (!waittime)
YX waittime = 1;
YX } else
YX waittime = MAXWAIT;
YX (void)signal(SIGALRM, finish);
YX (void)alarm((u_int)waittime);
YX }
YX}
YX
YX/*
YX * pinger --
YX * Compose and transmit an ICMP ECHO REQUEST packet. The IP packet
YX * will be added on by the kernel. The ID field is our UNIX process ID,
YX * and the sequence number is an ascending integer. The first 8 bytes
YX * of the data portion are used to hold a UNIX "timeval" struct in VAX
YX * byte-order, to compute the round-trip time.
YX */
YXpinger()
YX{
YX register struct icmp *icp;
YX register int cc;
YX int i;
YX
YX icp = (struct icmp *)outpack;
YX icp->icmp_type = ICMP_ECHO;
YX icp->icmp_code = 0;
YX icp->icmp_cksum = 0;
YX icp->icmp_seq = ntransmitted++;
YX icp->icmp_id = ident; /* ID */
YX
YX CLR(icp->icmp_seq % mx_dup_ck);
YX
YX if (timing)
YX (void)gettimeofday((struct timeval *)&outpack[8],
YX (struct timezone *)NULL);
YX
YX cc = datalen + 8; /* skips ICMP portion */
YX
YX /* compute ICMP checksum here */
YX icp->icmp_cksum = in_cksum((u_short *)icp, cc);
YX
YX i = sendto(s, (char *)outpack, cc, 0, &whereto,
YX sizeof(struct sockaddr));
YX
YX if (i < 0 || i != cc) {
YX if (i < 0)
YX perror("ping: sendto");
YX (void)printf("ping: wrote %s %d chars, ret=%d\n",
YX hostname, cc, i);
YX }
YX if (!(options & F_QUIET) && options & F_FLOOD)
YX (void)write(fileno(stdout), &DOT, 1);
YX}
YX
YX/*
YX * pr_pack --
YX * Print out the packet, if it came from us. This logic is necessary
YX * because ALL readers of the ICMP socket get a copy of ALL ICMP packets
YX * which arrive ('tis only fair). This permits multiple copies of this
YX * program to be run without having intermingled output (or statistics!).
YX */
YXpr_pack(buf, cc, from)
YX char *buf;
YX int cc;
YX struct sockaddr_in *from;
YX{
YX register struct icmp *icp;
YX register u_long l;
YX register int i, j;
YX register u_char *cp,*dp;
YX static int old_rrlen;
YX static char old_rr[MAX_IPOPTLEN];
YX struct ip *ip;
YX struct timeval tv, *tp;
YX double triptime;
YX int hlen, dupflag;
YX
YX (void)gettimeofday(&tv, (struct timezone *)NULL);
YX
YX /* Check the IP header */
YX ip = (struct ip *)buf;
YX hlen = ip->ip_hl << 2;
YX if (cc < hlen + ICMP_MINLEN) {
YX if (options & F_VERBOSE)
YX (void)fprintf(stderr,
YX "ping: packet too short (%d bytes) from %s\n", cc,
YX inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr));
YX return;
YX }
YX
YX /* Now the ICMP part */
YX cc -= hlen;
YX icp = (struct icmp *)(buf + hlen);
YX if (icp->icmp_type == ICMP_ECHOREPLY) {
YX if (icp->icmp_id != ident)
YX return; /* 'Twas not our ECHO */
YX ++nreceived;
YX if (timing) {
YX#ifndef icmp_data
YX tp = (struct timeval *)&icp->icmp_ip;
YX#else
YX tp = (struct timeval *)icp->icmp_data;
YX#endif
YX tvsub(&tv, tp);
YX triptime = ((double)tv.tv_sec) * 1000.0 +
YX ((double)tv.tv_usec) / 1000.0;
YX tsum += triptime;
YX if (triptime < tmin)
YX tmin = triptime;
YX if (triptime > tmax)
YX tmax = triptime;
YX }
YX
YX if (TST(icp->icmp_seq % mx_dup_ck)) {
YX ++nrepeats;
YX --nreceived;
YX dupflag = 1;
YX } else {
YX SET(icp->icmp_seq % mx_dup_ck);
YX dupflag = 0;
YX }
YX
YX if (options & F_QUIET)
YX return;
YX
YX if (options & F_FLOOD)
YX (void)write(fileno(stdout), &BSPACE, 1);
YX else {
YX (void)printf("%d bytes from %s: icmp_seq=%u", cc,
YX inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr),
YX icp->icmp_seq);
YX (void)printf(" ttl=%d", ip->ip_ttl);
YX if (timing)
YX (void)printf(" time=%g ms", triptime);
YX if (dupflag)
YX (void)printf(" (DUP!)");
YX /* check the data */
YX cp = (u_char*)&icp->icmp_data[8];
YX dp = &outpack[8 + sizeof(struct timeval)];
YX for (i = 8; i < datalen; ++i, ++cp, ++dp) {
YX if (*cp != *dp) {
YX (void)printf("\nwrong data byte #%d should be 0x%x but was 0x%x",
YX i, *dp, *cp);
YX cp = (u_char*)&icp->icmp_data[0];
YX for (i = 8; i < datalen; ++i, ++cp) {
YX if ((i % 32) == 8)
YX (void)printf("\n\t");
YX (void)printf("%x ", *cp);
YX }
YX break;
YX }
YX }
YX }
YX } else {
YX /* We've got something other than an ECHOREPLY */
YX if (!(options & F_VERBOSE))
YX return;
YX (void)printf("%d bytes from %s: ", cc,
YX pr_addr(from->sin_addr.s_addr));
YX pr_icmph(icp);
YX }
YX
YX /* Display any IP options */
YX cp = (u_char *)buf + sizeof(struct ip);
YX
YX for (; hlen > (int)sizeof(struct ip); --hlen, ++cp)
YX switch (*cp) {
YX case IPOPT_EOL:
YX hlen = 0;
YX break;
YX case IPOPT_LSRR:
YX (void)printf("\nLSRR: ");
YX hlen -= 2;
YX j = *++cp;
YX ++cp;
YX if (j > IPOPT_MINOFF)
YX for (;;) {
YX l = *++cp;
YX l = (l<<8) + *++cp;
YX l = (l<<8) + *++cp;
YX l = (l<<8) + *++cp;
YX if (l == 0)
YX (void)printf("\t0.0.0.0");
YX else
YX (void)printf("\t%s", pr_addr(ntohl(l)));
YX hlen -= 4;
YX j -= 4;
YX if (j <= IPOPT_MINOFF)
YX break;
YX (void)putchar('\n');
YX }
YX break;
YX case IPOPT_RR:
YX j = *++cp; /* get length */
YX i = *++cp; /* and pointer */
YX hlen -= 2;
YX if (i > j)
YX i = j;
YX i -= IPOPT_MINOFF;
YX if (i <= 0)
YX continue;
YX if (i == old_rrlen
YX && cp == (u_char *)buf + sizeof(struct ip) + 2
YX && !bcmp((char *)cp, old_rr, i)
YX && !(options & F_FLOOD)) {
YX (void)printf("\t(same route)");
YX i = ((i + 3) / 4) * 4;
YX hlen -= i;
YX cp += i;
YX break;
YX }
YX old_rrlen = i;
YX bcopy((char *)cp, old_rr, i);
YX (void)printf("\nRR: ");
YX for (;;) {
YX l = *++cp;
YX l = (l<<8) + *++cp;
YX l = (l<<8) + *++cp;
YX l = (l<<8) + *++cp;
YX if (l == 0)
YX (void)printf("\t0.0.0.0");
YX else
YX (void)printf("\t%s", pr_addr(ntohl(l)));
YX hlen -= 4;
YX i -= 4;
YX if (i <= 0)
YX break;
YX (void)putchar('\n');
YX }
YX break;
YX case IPOPT_NOP:
YX (void)printf("\nNOP");
YX break;
YX default:
YX (void)printf("\nunknown option %x", *cp);
YX break;
YX }
YX if (!(options & F_FLOOD)) {
YX (void)putchar('\n');
YX (void)fflush(stdout);
YX }
YX}
YX
YX/*
YX * in_cksum --
YX * Checksum routine for Internet Protocol family headers (C Version)
YX */
YXin_cksum(addr, len)
YX u_short *addr;
YX int len;
YX{
YX register int nleft = len;
YX register u_short *w = addr;
YX u_short answer = 0;
YX long sum = 0;
YX
YX /*
YX * Our algorithm is simple, using a 32 bit accumulator (sum), we add
YX * sequential 16 bit words to it, and at the end, fold back all the
YX * carry bits from the top 16 bits into the lower 16 bits.
YX */
YX while (nleft > 1) {
YX sum += *w++;
YX nleft -= 2;
YX }
YX
YX /* mop up an odd byte, if necessary */
YX if (nleft == 1) {
YX *(u_char *)(&answer) = *(u_char *)w ;
YX sum += answer;
YX }
YX
YX /* add back carry outs from top 16 bits to low 16 bits */
YX sum = (sum >> 16) + (sum & 0xffffL); /* add hi 16 to low 16 */
YX sum += (sum >> 16); /* add carry */
YX answer = ~sum; /* truncate to 16 bits */
YX return(answer);
YX}
YX
YX/*
YX * tvsub --
YX * Subtract 2 timeval structs: out = out - in. Out is assumed to
YX * be >= in.
YX */
YXtvsub(out, in)
YX register struct timeval *out, *in;
YX{
YX if ((out->tv_usec -= in->tv_usec) < 0) {
YX --out->tv_sec;
YX out->tv_usec += 1000000;
YX }
YX out->tv_sec -= in->tv_sec;
YX}
YX
YX/*
YX * finish --
YX * Print out statistics, and give up.
YX */
YXvoid
YXfinish()
YX{
YX register int i;
YX
YX (void)signal(SIGINT, SIG_IGN);
YX (void)putchar('\n');
YX (void)fflush(stdout);
YX (void)printf("--- %s ping statistics ---\n", hostname);
YX (void)printf("%ld packets transmitted, ", ntransmitted);
YX (void)printf("%ld packets received, ", nreceived);
YX if (nrepeats)
YX (void)printf("+%ld duplicates, ", nrepeats);
YX if (ntransmitted)
YX if (nreceived > ntransmitted)
YX (void)printf("-- somebody's printing up packets!");
YX else
YX (void)printf("%d%% packet loss",
YX (int) (((ntransmitted - nreceived) * 100) /
YX ntransmitted));
YX (void)putchar('\n');
YX if (nreceived && timing) {
YX /* Only display average to microseconds */
YX i = 1000.0 * tsum / (nreceived + nrepeats);
YX (void)printf("round-trip min/avg/max = %g/%g/%g ms\n",
YX tmin, ((double)i) / 1000.0, tmax);
YX }
YX exit(0);
YX}
YX
YX#ifdef notdef
YXstatic char *ttab[] = {
YX "Echo Reply", /* ip + seq + udata */
YX "Dest Unreachable", /* net, host, proto, port, frag, sr + IP */
YX "Source Quench", /* IP */
YX "Redirect", /* redirect type, gateway, + IP */
YX "Echo",
YX "Time Exceeded", /* transit, frag reassem + IP */
YX "Parameter Problem", /* pointer + IP */
YX "Timestamp", /* id + seq + three timestamps */
YX "Timestamp Reply", /* " */
YX "Info Request", /* id + sq */
YX "Info Reply" /* " */
YX};
YX#endif
YX
YX/*
YX * pr_icmph --
YX * Print a descriptive string about an ICMP header.
YX */
YXpr_icmph(icp)
YX struct icmp *icp;
YX{
YX switch(icp->icmp_type) {
YX case ICMP_ECHOREPLY:
YX (void)printf("Echo Reply\n");
YX /* XXX ID + Seq + Data */
YX break;
YX case ICMP_UNREACH:
YX switch(icp->icmp_code) {
YX case ICMP_UNREACH_NET:
YX (void)printf("Destination Net Unreachable\n");
YX break;
YX case ICMP_UNREACH_HOST:
YX (void)printf("Destination Host Unreachable\n");
YX break;
YX case ICMP_UNREACH_PROTOCOL:
YX (void)printf("Destination Protocol Unreachable\n");
YX break;
YX case ICMP_UNREACH_PORT:
YX (void)printf("Destination Port Unreachable\n");
YX break;
YX case ICMP_UNREACH_NEEDFRAG:
YX (void)printf("frag needed and DF set\n");
YX break;
YX case ICMP_UNREACH_SRCFAIL:
YX (void)printf("Source Route Failed\n");
YX break;
YX default:
YX (void)printf("Dest Unreachable, Bad Code: %d\n",
YX icp->icmp_code);
YX break;
YX }
YX /* Print returned IP header information */
YX#ifndef icmp_data
YX pr_retip(&icp->icmp_ip);
YX#else
YX pr_retip((struct ip *)icp->icmp_data);
YX#endif
YX break;
YX case ICMP_SOURCEQUENCH:
YX (void)printf("Source Quench\n");
YX#ifndef icmp_data
YX pr_retip(&icp->icmp_ip);
YX#else
YX pr_retip((struct ip *)icp->icmp_data);
YX#endif
YX break;
YX case ICMP_REDIRECT:
YX switch(icp->icmp_code) {
YX case ICMP_REDIRECT_NET:
YX (void)printf("Redirect Network");
YX break;
YX case ICMP_REDIRECT_HOST:
YX (void)printf("Redirect Host");
YX break;
YX case ICMP_REDIRECT_TOSNET:
YX (void)printf("Redirect Type of Service and Network");
YX break;
YX case ICMP_REDIRECT_TOSHOST:
YX (void)printf("Redirect Type of Service and Host");
YX break;
YX default:
YX (void)printf("Redirect, Bad Code: %d", icp->icmp_code);
YX break;
YX }
YX (void)printf("(New addr: 0x%08lx)\n", icp->icmp_gwaddr.s_addr);
YX#ifndef icmp_data
YX pr_retip(&icp->icmp_ip);
YX#else
YX pr_retip((struct ip *)icp->icmp_data);
YX#endif
YX break;
YX case ICMP_ECHO:
YX (void)printf("Echo Request\n");
YX /* XXX ID + Seq + Data */
YX break;
YX case ICMP_TIMXCEED:
YX switch(icp->icmp_code) {
YX case ICMP_TIMXCEED_INTRANS:
YX (void)printf("Time to live exceeded\n");
YX break;
YX case ICMP_TIMXCEED_REASS:
YX (void)printf("Frag reassembly time exceeded\n");
YX break;
YX default:
YX (void)printf("Time exceeded, Bad Code: %d\n",
YX icp->icmp_code);
YX break;
YX }
YX#ifndef icmp_data
YX pr_retip(&icp->icmp_ip);
YX#else
YX pr_retip((struct ip *)icp->icmp_data);
YX#endif
YX break;
YX case ICMP_PARAMPROB:
YX (void)printf("Parameter problem: pointer = 0x%02x\n",
YX icp->icmp_hun.ih_pptr);
YX#ifndef icmp_data
YX pr_retip(&icp->icmp_ip);
YX#else
YX pr_retip((struct ip *)icp->icmp_data);
YX#endif
YX break;
YX case ICMP_TSTAMP:
YX (void)printf("Timestamp\n");
YX /* XXX ID + Seq + 3 timestamps */
YX break;
YX case ICMP_TSTAMPREPLY:
YX (void)printf("Timestamp Reply\n");
YX /* XXX ID + Seq + 3 timestamps */
YX break;
YX case ICMP_IREQ:
YX (void)printf("Information Request\n");
YX /* XXX ID + Seq */
YX break;
YX case ICMP_IREQREPLY:
YX (void)printf("Information Reply\n");
YX /* XXX ID + Seq */
YX break;
YX#ifdef ICMP_MASKREQ
YX case ICMP_MASKREQ:
YX (void)printf("Address Mask Request\n");
YX break;
YX#endif
YX#ifdef ICMP_MASKREPLY
YX case ICMP_MASKREPLY:
YX (void)printf("Address Mask Reply\n");
YX break;
YX#endif
YX default:
YX (void)printf("Bad ICMP type: %d\n", icp->icmp_type);
YX }
YX}
YX
YX/*
YX * pr_iph --
YX * Print an IP header with options.
YX */
YXpr_iph(ip)
YX struct ip *ip;
YX{
YX int hlen;
YX u_char *cp;
YX
YX hlen = ip->ip_hl << 2;
YX cp = (u_char *)ip + 20; /* point to options */
YX
YX (void)printf("Vr HL TOS Len ID Flg off TTL Pro cks Src Dst Data\n");
YX (void)printf(" %1x %1x %02x %04x %04x",
YX ip->ip_v, ip->ip_hl, ip->ip_tos, ip->ip_len, ip->ip_id);
YX (void)printf(" %1x %04x", ((ip->ip_off) & 0xe000) >> 13,
YX (ip->ip_off) & 0x1fff);
YX (void)printf(" %02x %02x %04x", ip->ip_ttl, ip->ip_p, ip->ip_sum);
YX (void)printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->ip_src.s_addr));
YX (void)printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->ip_dst.s_addr));
YX /* dump and option bytes */
YX while (hlen-- > 20) {
YX (void)printf("%02x", *cp++);
YX }
YX (void)putchar('\n');
YX}
YX
YX/*
YX * pr_addr --
YX * Return an ascii host address as a dotted quad and optionally with
YX * a hostname.
YX */
YXchar *
YXpr_addr(l)
YX u_long l;
YX{
YX struct hostent *hp;
YX static char buf[80];
YX
YX if ((options & F_NUMERIC) ||
YX !(hp = gethostbyaddr((char *)&l, 4, AF_INET)))
YX (void)sprintf(buf, "%s", inet_ntoa(*(struct in_addr *)&l));
YX else
YX (void)sprintf(buf, "%s (%s)", hp->h_name,
YX inet_ntoa(*(struct in_addr *)&l));
YX return(buf);
YX}
YX
YX/*
YX * pr_retip --
YX * Dump some info on a returned (via ICMP) IP packet.
YX */
YXpr_retip(ip)
YX struct ip *ip;
YX{
YX int hlen;
YX u_char *cp;
YX
YX pr_iph(ip);
YX hlen = ip->ip_hl << 2;
YX cp = (u_char *)ip + hlen;
YX
YX if (ip->ip_p == 6)
YX (void)printf("TCP: from port %u, to port %u (decimal)\n",
YX (*cp * 256 + *(cp + 1)), (*(cp + 2) * 256 + *(cp + 3)));
YX else if (ip->ip_p == 17)
YX (void)printf("UDP: from port %u, to port %u (decimal)\n",
YX (*cp * 256 + *(cp + 1)), (*(cp + 2) * 256 + *(cp + 3)));
YX}
YX
YXfill(bp, patp)
YX char *bp, *patp;
YX{
YX register int ii, jj, kk;
YX int pat[16];
YX char *cp;
YX
YX for (cp = patp; *cp; cp++)
YX if (!isxdigit(*cp)) {
YX (void)fprintf(stderr,
YX "ping: patterns must be specified as hex digits.\n");
YX exit(1);
YX }
YX ii = sscanf(patp,
YX "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
YX &pat[0], &pat[1], &pat[2], &pat[3], &pat[4], &pat[5], &pat[6],
YX &pat[7], &pat[8], &pat[9], &pat[10], &pat[11], &pat[12],
YX &pat[13], &pat[14], &pat[15]);
YX
YX if (ii > 0)
YX for (kk = 0;
YX kk <= MAXPACKET - (8 + sizeof(struct timeval) + ii);
YX kk += ii)
YX for (jj = 0; jj < ii; ++jj)
YX bp[jj + kk] = pat[jj];
YX if (!(options & F_QUIET)) {
YX (void)printf("PATTERN: 0x");
YX for (jj = 0; jj < ii; ++jj)
YX (void)printf("%02x", bp[jj] & 0xFF);
YX (void)printf("\n");
YX }
YX}
YX
YXusage()
YX{
YX (void)fprintf(stderr,
YX "usage: ping [-Rdfnqrv] [-c count] [-i wait] [-l preload]\n\t[-p pattern] [-s packetsize] host\n");
YX exit(1);
YX}
YSHAR_EOF
Ychmod 644 'ping.c'
Yfi
Ychmod 755 .
Ycd ..
Yif test -f '/usr/src/lib/libc/gen/getmntinfo.c'
Ythen
Y echo shar: "will not over-write existing file '/usr/src/lib/libc/gen/getmntinfo.c'"
Yelse
Ysed 's/^X//' << \SHAR_EOF > '/usr/src/lib/libc/gen/getmntinfo.c'
YX/*
YX * Copyright (c) 1989, 1993
YX * The Regents of the University of California. All rights reserved.
YX *
YX * Redistribution and use in source and binary forms, with or without
YX * modification, are permitted provided that the following conditions
YX * are met:
YX * 1. Redistributions of source code must retain the above copyright
YX * notice, this list of conditions and the following disclaimer.
YX * 2. Redistributions in binary form must reproduce the above copyright
YX * notice, this list of conditions and the following disclaimer in the
YX * documentation and/or other materials provided with the distribution.
YX * 3. All advertising materials mentioning features or use of this software
YX * must display the following acknowledgement:
YX * This product includes software developed by the University of
YX * California, Berkeley and its contributors.
YX * 4. Neither the name of the University nor the names of its contributors
YX * may be used to endorse or promote products derived from this software
YX * without specific prior written permission.
YX *
YX * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
YX * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
YX * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
YX * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
YX * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
YX * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
YX * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
YX * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
YX * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
YX * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
YX * SUCH DAMAGE.
YX */
YX
YX#if defined(LIBC_SCCS) && !defined(lint)
YXstatic char sccsid[] = "@(#)getmntinfo.c 8.1.1 (2.11BSD) 1995/12/26";
YX#endif /* LIBC_SCCS and not lint */
YX
YX#include <sys/param.h>
YX#include <sys/mount.h>
YX#include <stdlib.h>
YX
YX/*
YX * Return information about mounted filesystems.
YX */
YXint
YXgetmntinfo(mntbufp, flags)
YX register struct statfs **mntbufp;
YX int flags;
YX{
YX static struct statfs *mntbuf;
YX static int mntsize;
YX static int bufsize;
YX
YX if (mntsize <= 0 && (mntsize = getfsstat(0, 0, MNT_NOWAIT)) < 0)
YX return (0);
YX if (bufsize > 0 && (mntsize = getfsstat(mntbuf, bufsize, flags)) < 0)
YX return (0);
YX while (bufsize <= mntsize * sizeof(struct statfs)) {
YX if (mntbuf)
YX free(mntbuf);
YX bufsize = (mntsize + 1) * sizeof(struct statfs);
YX if ((mntbuf = (struct statfs *)malloc(bufsize)) == 0)
YX return (0);
YX if ((mntsize = getfsstat(mntbuf, bufsize, flags)) < 0)
YX return (0);
YX }
YX *mntbufp = mntbuf;
YX return (mntsize);
YX}
YSHAR_EOF
Ychmod 644 '/usr/src/lib/libc/gen/getmntinfo.c'
Yfi
Yif test -f '/usr/src/man/man2/getfsstat.2'
Ythen
Y echo shar: "will not over-write existing file '/usr/src/man/man2/getfsstat.2'"
Yelse
Ysed 's/^X//' << \SHAR_EOF > '/usr/src/man/man2/getfsstat.2'
YX.\" Copyright (c) 1989, 1991, 1993
YX.\" The Regents of the University of California. All rights reserved.
YX.\"
YX.\" Redistribution and use in source and binary forms, with or without
YX.\" modification, are permitted provided that the following conditions
YX.\" are met:
YX.\" 1. Redistributions of source code must retain the above copyright
YX.\" notice, this list of conditions and the following disclaimer.
YX.\" 2. Redistributions in binary form must reproduce the above copyright
YX.\" notice, this list of conditions and the following disclaimer in the
YX.\" documentation and/or other materials provided with the distribution.
YX.\" 3. All advertising materials mentioning features or use of this software
YX.\" must display the following acknowledgement:
YX.\" This product includes software developed by the University of
YX.\" California, Berkeley and its contributors.
YX.\" 4. Neither the name of the University nor the names of its contributors
YX.\" may be used to endorse or promote products derived from this software
YX.\" without specific prior written permission.
YX.\"
YX.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
YX.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
YX.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
YX.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
YX.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
YX.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
YX.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
YX.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
YX.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
YX.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
YX.\" SUCH DAMAGE.
YX.\"
YX.\" @(#)getfsstat.2 8.1.1 (2.11BSD) 1995/12/24
YX.\"
YX.TH GETFSSTAT 2 "December 24, 1995"
YX.UC 7
YX.SH NAME
YX\fBgetfsstat\fP \- get list of all mounted filesystems
YX.SH SYNOPSIS
YX.B #include <sys/param.h>
YX.br
YX.B #include <sys/mount.h>
YX.sp
YX.I int
YX.br
YX\fBgetfsstat\fP(buf,bufsize,flags)
YX.br
YX.I struct statfs *buf;
YX.br
YX.I int bufsize;
YX.br
YX.I int flags;
YX.br
YX.SH DESCRIPTION
YX.BR Getfsstat ()
YXreturns information about all mounted filesystems.
YX.I Buf
YXis a pointer to
YX.I statfs
YXstructures defined as follows:
YX.sp
YX.nf
YX.cs R 20
YX
YX#define MNAMELEN 90 /* length of buffer for returned name */
YX
YXstruct statfs {
YXshort f_type; /* type of filesystem (see below) */
YXshort f_flags; /* copy of mount flags */
YXshort f_bsize; /* fundamental file system block size */
YXshort f_iosize; /* optimal transfer block size */
YXlong f_blocks; /* total data blocks in file system */
YXlong f_bfree; /* free blocks in fs */
YXlong f_bavail; /* free blocks avail to non-superuser */
YXino_t f_files; /* total file nodes in file system */
YXino_t f_ffree; /* free file nodes in fs */
YXu_long f_fsid[2]; /* file system id */
YXlong f_spare[4]; /* spare for later */
YXchar f_mntonname[MNAMELEN]; /* mount point */
YXchar f_mntfromname[MNAMELEN]; /* mounted filesystem */
YX};
YX/*
YX* File system types. - Only UFS is supported so the other types are not
YX* given.
YX*/
YX#define MOUNT_NONE 0
YX#define MOUNT_UFS 1 /* Fast Filesystem */
YX.br
YX.fi
YX.cs R
YX.PP
YXFields that are undefined for a particular filesystem are set to -1.
YXThe buffer is filled with an array of
YX.I fsstat
YXstructures, one for each mounted filesystem
YXup to the size specified by
YX.IR bufsize .
YX.PP
YXIf
YX.I buf
YXis given as NULL,
YX.BR getfsstat ()
YXreturns just the number of mounted filesystems.
YX.PP
YXNormally
YX.I flags
YXis currently unused. In 4.4BSD systems the usage is
YXspecified as
YXMNT_WAIT.
YXIf
YX.I flags
YXis set to
YXMNT_NOWAIT,
YX.BR getfsstat ()
YXwill return the information it has available without requesting
YXan update from each filesystem.
YXThus, some of the information will be out of date, but
YX.BR getfsstat ()
YXwill not block waiting for information from a filesystem that is
YXunable to respond.
YX.SH RETURN VALUES
YXUpon successful completion, the number of
YX.I fsstat
YXstructures is returned.
YXOtherwise, -1 is returned and the global variable
YX.I errno
YXis set to indicate the error.
YX.SH ERRORS
YX.BR Getfsstat ()
YXfails if one or more of the following are true:
YX.sp
YX.TP 20
YX[EFAULT]
YX.I Buf
YXpoints to an invalid address.
YX.TP 20
YX[EIO]
YXAn I/O
YXerror occurred while reading from or writing to the filesystem.
YX.SH SEE ALSO
YXstatfs(2), fstab(5), mount(8)
YX.SH HISTORY
YXThe
YX.B getfsstat
YXfunction first appeared in 4.4BSD.
YSHAR_EOF
Ychmod 644 '/usr/src/man/man2/getfsstat.2'
Yfi
Yif test -f '/usr/src/man/man2/statfs.2'
Ythen
Y echo shar: "will not over-write existing file '/usr/src/man/man2/statfs.2'"
Yelse
Ysed 's/^X//' << \SHAR_EOF > '/usr/src/man/man2/statfs.2'
YX.\" Copyright (c) 1989, 1991, 1993
YX.\" The Regents of the University of California. All rights reserved.
YX.\"
YX.\" Redistribution and use in source and binary forms, with or without
YX.\" modification, are permitted provided that the following conditions
YX.\" are met:
YX.\" 1. Redistributions of source code must retain the above copyright
YX.\" notice, this list of conditions and the following disclaimer.
YX.\" 2. Redistributions in binary form must reproduce the above copyright
YX.\" notice, this list of conditions and the following disclaimer in the
YX.\" documentation and/or other materials provided with the distribution.
YX.\" 3. All advertising materials mentioning features or use of this software
YX.\" must display the following acknowledgement:
YX.\" This product includes software developed by the University of
YX.\" California, Berkeley and its contributors.
YX.\" 4. Neither the name of the University nor the names of its contributors
YX.\" may be used to endorse or promote products derived from this software
YX.\" without specific prior written permission.
YX.\"
YX.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
YX.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
YX.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
YX.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
YX.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
YX.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
YX.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
YX.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
YX.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
YX.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
YX.\" SUCH DAMAGE.
YX.\"
YX.\" @(#)statfs.2 8.3.2 (2.11BSD) 1995/12/26
YX.\"
YX.TH STATFS 2 "December 26, 1995"
YX.UC 7
YX.SH NAME
YX\fBstatfs\fP, \fBfstatfs\fP \- get file system statistics
YX.SH SYNOPSIS
YX.B #include <sys/param.h>
YX.br
YX.B #include <sys/mount.h>
YX.sp
YX.I int
YX.br
YX\fBstatfs\fP(path,buf)
YX.br
YX.I char *path;
YX.br
YX.I struct statfs *buf;
YX.sp
YX.I int
YX.br
YX\fBfstatfs\fP(fd,buf)
YX.br
YX.I int fd;
YX.br
YX.I struct statfs *buf;
YX.SH DESCRIPTION
YX.BR Statfs ()
YXreturns information about a mounted file system.
YX.I Path
YXis the path name of any file within the mounted filesystem.
YX.I Buf
YXis a pointer to a
YX.I statfs
YXstructure defined as follows:
YX.sp
YX.nf
YX.cs R 20
YX
YX#define MNAMELEN 90 /* length of buffer for returned name */
YX
YXstruct statfs {
YXshort f_type; /* type of filesystem (see below) */
YXshort f_flags; /* copy of mount flags */
YXshort f_bsize; /* fundamental file system block size */
YXshort f_iosize; /* optimal transfer block size */
YXlong f_blocks; /* total data blocks in file system */
YXlong f_bfree; /* free blocks in fs */
YXlong f_bavail; /* free blocks avail to non-superuser */
YXino_t f_files; /* total file nodes in file system */
YXino_t f_ffree; /* free file nodes in fs */
YXu_long f_fsid[2]; /* file system id */
YXlong f_spare[4]; /* spare for later */
YXchar f_mntonname[MNAMELEN]; /* mount point */
YXchar f_mntfromname[MNAMELEN]; /* mounted filesystem */
YX};
YX/*
YX* File system types. - Only UFS is supported so the other types are not
YX* given.
YX*/
YX#define MOUNT_UFS 1 /* Fast Filesystem */
YX.br
YX.fi
YX.cs R
YX.PP
YXFields that are undefined for a particular file system are set to -1.
YX.BR Fstatfs ()
YXreturns the same information about an open file referenced by descriptor
YX.IR fd .
YX.SH RETURN VALUES
YXUpon successful completion, a value of 0 is returned.
YXOtherwise, -1 is returned and the global variable
YX.I errno
YXis set to indicate the error.
YX.SH ERRORS
YX.BR Statfs ()
YXfails if one or more of the following are true:
YX.sp
YX.TP 20
YX[ENOTDIR]
YXA component of the path prefix of
YX.I Path
YXis not a directory.
YX.TP 20
YX[EINVAL]
YX.I path
YXcontains a character with the high-order bit set.
YX.TP 20
YX[ENAMETOOLONG]
YXThe length of a component of
YX.I path
YXexceeds 63 characters,
YXor the length of
YX.I path
YXexceeds 255 characters.
YX.TP 20
YX[ENOENT]
YXThe file referred to by
YX.I path
YXdoes not exist.
YX.TP 20
YX[EACCES]
YXSearch permission is denied for a component of the path prefix of
YX.IR path .
YX.TP 20
YX[ELOOP]
YXToo many symbolic links were encountered in translating
YX.IR path .
YX.TP 20
YX[EFAULT]
YX.I Buf
YXor
YX.I path
YXpoints to an invalid address.
YX.TP 20
YX[EIO]
YXAn
YXI/O
YXerror occurred while reading from or writing to the file system.
YX.PP
YX.BR Fstatfs ()
YXfails if one or more of the following are true:
YX.sp
YX.TP 20
YX[EBADF]
YX.I Fd
YXis not a valid open file descriptor.
YX.TP 20
YX[EFAULT]
YX.I Buf
YXpoints to an invalid address.
YX.TP 20
YX[EIO]
YXAn
YXI/O
YXerror occurred while reading from or writing to the file system.
YX.SH HISTORY
YXThe
YX.B statfs
YXfunction first appeared in 4.4BSD.
YSHAR_EOF
Ychmod 644 '/usr/src/man/man2/statfs.2'
Yfi
Yif test -f '/usr/src/man/man3/getmntinfo.3'
Ythen
Y echo shar: "will not over-write existing file '/usr/src/man/man3/getmntinfo.3'"
Yelse
Ysed 's/^X//' << \SHAR_EOF > '/usr/src/man/man3/getmntinfo.3'
YX.\" Copyright (c) 1989, 1991, 1993
YX.\" The Regents of the University of California. All rights reserved.
YX.\"
YX.\" Redistribution and use in source and binary forms, with or without
YX.\" modification, are permitted provided that the following conditions
YX.\" are met:
YX.\" 1. Redistributions of source code must retain the above copyright
YX.\" notice, this list of conditions and the following disclaimer.
YX.\" 2. Redistributions in binary form must reproduce the above copyright
YX.\" notice, this list of conditions and the following disclaimer in the
YX.\" documentation and/or other materials provided with the distribution.
YX.\" 3. All advertising materials mentioning features or use of this software
YX.\" must display the following acknowledgement:
YX.\" This product includes software developed by the University of
YX.\" California, Berkeley and its contributors.
YX.\" 4. Neither the name of the University nor the names of its contributors
YX.\" may be used to endorse or promote products derived from this software
YX.\" without specific prior written permission.
YX.\"
YX.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
YX.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
YX.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
YX.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
YX.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
YX.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
YX.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
YX.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
YX.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
YX.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
YX.\" SUCH DAMAGE.
YX.\"
YX.\" @(#)getmntinfo.3 8.1.1 (2.11BSD) 1995/12/26
YX.\"
YX.TH GETMNTINFO 3 "December 26, 1995"
YX.UC 7
YX.SH NAME
YX\fBgetmntinfo\fP \- get information about mounted file systems
YX.SH SYNOPSIS
YX.B #include <sys/param.h>
YX.br
YX.B #include <sys/mount.h>
YX.sp
YX.I int
YX.br
YX\fBgetmntinfo\fP(mntbufp,flags)
YX.br
YX.I struct statfs **mntbufp;
YX.br
YX.I int flags
YX.br
YX.SH DESCRIPTION
YXThe
YX.BR getmntinfo ()
YXfunction
YXreturns an array of
YX.I statfs
YXstructures describing each currently mounted file system (see
YX.BR statfs (2).
YX.PP
YXThe
YX.BR getmntinfo ()
YXfunction
YXpasses its
YX.I flags
YXparameter transparently to
YX.BR getfsstat (2).
YX.SH RETURN VALUES
YXOn successful completion,
YX.BR getmntinfo ()
YXreturns a count of the number of elements in the array.
YXThe pointer to the array is stored into
YX.IR mntbufp .
YX.PP
YXIf an error occurs, zero is returned and the external variable
YX.I errno
YXis set to indicate the error.
YXAlthough the pointer
YX.I mntbufp
YXwill be unmodified, any information previously returned by
YX.BR getmntinfo ()
YXwill be lost.
YX.SH ERRORS
YXThe
YX.BR getmntinfo ()
YXfunction
YXmay fail and set errno for any of the errors specified for the library
YXroutines
YX.BR getfsstat (2)
YXor
YX.BR malloc (3).
YX.SH SEE ALSO
YXgetfsstat(2),
YXstatfs(2),
YXmount(2),
YXmount(8)
YX.SH HISTORY
YXThe
YX.BR getmntinfo ()
YXfunction first appeared in 4.4BSD.
YX.SH BUGS
YXThe
YX.BR getmntinfo ()
YXfunction writes the array of structures to an internal static object
YXand returns
YXa pointer to that object. Subsequent calls to
YX.BR getmntinfo ()
YXwill modify the same object.
YX.PP
YXThe memory allocated by
YX.BR getmntinfo ()
YXcannot be
YX.BR free (2)'d
YXby the application.
YSHAR_EOF
Ychmod 644 '/usr/src/man/man3/getmntinfo.3'
Yfi
Yif test -f '/usr/src/sys/h/stddef.h'
Ythen
Y echo shar: "will not over-write existing file '/usr/src/sys/h/stddef.h'"
Yelse
Ysed 's/^X//' << \SHAR_EOF > '/usr/src/sys/h/stddef.h'
YX/*-
YX * Copyright (c) 1990, 1993
YX * The Regents of the University of California. All rights reserved.
YX *
YX * Redistribution and use in source and binary forms, with or without
YX * modification, are permitted provided that the following conditions
YX * are met:
YX * 1. Redistributions of source code must retain the above copyright
YX * notice, this list of conditions and the following disclaimer.
YX * 2. Redistributions in binary form must reproduce the above copyright
YX * notice, this list of conditions and the following disclaimer in the
YX * documentation and/or other materials provided with the distribution.
YX * 3. All advertising materials mentioning features or use of this software
YX * must display the following acknowledgement:
YX * This product includes software developed by the University of
YX * California, Berkeley and its contributors.
YX * 4. Neither the name of the University nor the names of its contributors
YX * may be used to endorse or promote products derived from this software
YX * without specific prior written permission.
YX *
YX * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
YX * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
YX * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
YX * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
YX * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
YX * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
YX * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
YX * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
YX * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
YX * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
YX * SUCH DAMAGE.
YX *
YX * @(#)stddef.h 8.1 (Berkeley) 6/2/93
YX */
YX
YX#ifndef _STDDEF_H_
YX#define _STDDEF_H_
YX
YX/* #include <machine/ansi.h> */
YX
YX#define offsetof(type, member) ((size_t)(&((type *)0)->member))
YX
YX#endif /* _STDDEF_H_ */
YSHAR_EOF
Ychmod 444 '/usr/src/sys/h/stddef.h'
Yfi
Yif test -f '/usr/src/sys/pdp/mscp_common.h'
Ythen
Y echo shar: "will not over-write existing file '/usr/src/sys/pdp/mscp_common.h'"
Yelse
Ysed 's/^X//' << \SHAR_EOF > '/usr/src/sys/pdp/mscp_common.h'
YX/*
YX * 1.1 (2.11BSD) 1995/12/12
YX *
YX * Definitions common to both MSCP and TMSCP were moved here from tmscp.h.
YX * Eventually the MSCP driver and include file will be modified to use these
YX * instead of their private versions.
YX*/
YX
YX#ifndef _MSCP_COMMON_H_
YX#define _MSCP_COMMON_H_
YX
YX/*
YX * Control message opcodes
YX*/
YX#define M_OP_ABORT 0x01 /* Abort command */
YX#define M_OP_GTCMD 0x02 /* Get command status command */
YX#define M_OP_GTUNT 0x03 /* Get unit status command */
YX#define M_OP_STCON 0x04 /* Set controller characteristics command */
YX#define M_OP_ACCNM 0x05 /* Access non volatile memory */
YX#define M_OP_SEREX 0x07 /* Serious exceptin message */
YX#define M_OP_AVAIL 0x08 /* Available command */
YX#define M_OP_ONLIN 0x09 /* Online command */
YX#define M_OP_STUNT 0x0a /* Set unit characteristics command */
YX#define M_OP_DTACP 0x0b /* Determine access paths command */
YX#define M_OP_ACCES 0x10 /* Access command */
YX#define M_OP_CMPCD 0x11 /* Compare controller data command */
YX#define M_OP_ERASE 0x12 /* Erase command */
YX#define M_OP_FLUSH 0x13 /* Flush command */
YX#define M_OP_ERGAP 0x16 /* Erase gap command */
YX#define M_OP_COMP 0x20 /* Compare host data command */
YX#define M_OP_READ 0x21 /* Read command */
YX#define M_OP_WRITE 0x22 /* Write command */
YX#define M_OP_WRITM 0x24 /* Write tape mark command */
YX#define M_OP_REPOS 0x25 /* Reposition command */
YX /* 0x28 thru 0x2f reserved */
YX#define M_OP_AVATN 0x40 /* Available attention message */
YX#define M_OP_DUPUN 0x41 /* Duplicate unit number attention message */
YX#define M_OP_ACPTH 0x42 /* Access path attention message */
YX#define M_OP_RWATN 0x43 /* Rewind attention message */
YX#define M_OP_END 0x80 /* End message flag */
YX
YX/*
YX * Generic command modifiers
YX */
YX#define M_MD_EXPRS 0x8000 /* Express request */
YX#define M_MD_COMP 0x4000 /* Compare */
YX#define M_MD_CLSEX 0x2000 /* Clear serious exception */
YX#define M_MD_CDATL 0x1000 /* Clear cache data lost exception */
YX#define M_MD_SCCHH 0x0800 /* Suppress caching (high speed) */
YX#define M_MD_SCCHL 0x0400 /* Suppress caching (low speed) */
YX#define M_MD_SECOR 0x0200 /* Suppress error correction */
YX#define M_MD_SEREC 0x0100 /* Suppress error recovery */
YX#define M_MD_WBKNV 0x0040 /* Write back non volative mem */
YX#define M_MD_IMMED 0x0040 /* Immediate completion */
YX#define M_MD_WBKVL 0x0020 /* Write back volatile mem */
YX#define M_MD_UNLOD 0x0010 /* Unload */
YX#define M_MD_REVRS 0x0008 /* reverse */
YX
YX/*
YX * Repositioning command modifiers
YX */
YX#define M_MD_DLEOT 0x0080 /* delete LEOT */
YX#define M_MD_OBJCT 0x0004 /* object count */
YX#define M_MD_REWND 0x0002 /* rewind */
YX
YX/*
YX * Available command modifiers
YX*/
YX#define M_MD_ALLCD 0x0002 /* All class drivers */
YX#define M_MD_SPNDW 0x0001 /* Spin down */
YX
YX/*
YX * Flush command modifiers
YX*/
YX#define M_MD_VOLTL 0x0002 /* Volatile memory only */
YX#define M_MD_FLENU 0x0001 /* Flush entire unit's memory */
YX
YX/*
YX * Get unit status command modifiers
YX*/
YX#define M_MD_NXUNT 0x0001 /* Get next unit */
YX
YX/*
YX * Online and set unit char command modifiers
YX*/
YX#define M_MD_EXCAC 0x0020 /* Exclusive access */
YX#define M_MD_STWRP 0x0004 /* Enable write protect */
YX
YX/*
YX * End message flags
YX */
YX#define M_EF_ERLOG 0x0020 /* Error log generated */
YX#define M_EF_SEREX 0x0010 /* Serious exception */
YX#define M_EF_EOT 0x0008 /* End of tape encountered */
YX#define M_EF_PLS 0x0004 /* Position lost */
YX#define M_EF_DLS 0x0002 /* Cache data lost */
YX
YX/*
YX * Controller flags
YX */
YX#define M_CF_ATTN 0x0080 /* Enable attention messages */
YX#define M_CF_MISC 0x0040 /* Enable miscellaneous error log messages */
YX#define M_CF_OTHER 0x0020 /* Enable other host's error log messages */
YX#define M_CF_THIS 0x0010 /* Enable this host's error log messages */
YX
YX
YX/*
YX * Unit flags
YX */
YX#define M_UF_CACH 0x8000 /* Set if caching capable */
YX#define M_UF_WRTPH 0x2000 /* Write protect (hardware) */
YX#define M_UF_WRTPS 0x1000 /* Write protect (software or volume) */
YX#define M_UF_SCCHH 0x0800 /* Suppress caching */
YX#define M_UF_EXACC 0x0400 /* Exclusive access */
YX#define M_UF_LOADR 0x0200 /* Tape loader present */
YX#define M_UF_WRTPD 0x0100 /* Write protect (data safety) */
YX#define M_UF_RMVBL 0x0080 /* Removable media */
YX#define M_UF_WBKNV 0x0040 /* Write back (enables cache) */
YX#define M_UF_VSMSU 0x0020 /* Variable speed mode suppression */
YX#define M_UF_VARSP 0x0010 /* Variable speed unit */
YX#define M_UF_CACFL 0x0004 /* Cache has been flushed */
YX#define M_UF_CMPWR 0x0002 /* Compare writes */
YX#define M_UF_CMPRD 0x0001 /* Compare reads */
YX
YX/*
YX * Status codes
YX */
YX#define M_ST_MASK 0x1f /* Status code mask */
YX#define M_ST_SBCOD 0x20 /* sub code multiplier */
YX#define M_ST_SBBIT 0x05 /* Sub code starting bit position */
YX
YX#define M_ST_SUCC 0x00 /* Success */
YX#define M_ST_ICMD 0x01 /* Invalid command */
YX#define M_ST_ABRTD 0x02 /* Command aborted */
YX#define M_ST_OFFLN 0x03 /* Unit offline */
YX#define M_ST_AVLBL 0x04 /* Unit available */
YX#define M_ST_MFMTE 0x05 /* Media format error */
YX#define M_ST_WRTPR 0x06 /* Write protected */
YX#define M_ST_COMP 0x07 /* Compare error */
YX#define M_ST_DATA 0x08 /* Data error */
YX#define M_ST_HSTBF 0x09 /* Host buffer access error */
YX#define M_ST_CNTLR 0x0a /* Controller error */
YX#define M_ST_DRIVE 0x0b /* Drive error */
YX#define M_ST_FMTER 0x0c /* Formatter error */
YX#define M_ST_BOT 0x0d /* BOT encountered */
YX#define M_ST_TAPEM 0x0e /* Tape mark encountered */
YX#define M_ST_RDTRN 0x10 /* Record data truncated */
YX#define M_ST_PLOST 0x11 /* Position lost */
YX#define M_ST_SEX 0x12 /* Serious exception */
YX#define M_ST_LED 0x13 /* LEOT detected */
YX#define M_ST_BBR 0x14 /* Bad block replacement complete */
YX#define M_ST_IPARM 0x15 /* Invalid parameter */
YX#define M_ST_INFO 0x16 /* Informational message, not error */
YX#define M_ST_LOADR 0x17 /* Media loader error */
YX#define M_ST_DIAG 0x1f /* Message from internal diagnostic */
YX
YX/*
YX * Success subcodes
YX*/
YX#define M_SC_NORML 0x0000 /* Normal */
YX#define M_SC_SDIGN 0x0001 /* Spin down ignored */
YX#define M_SC_STCON 0x0002 /* Still connected */
YX#define M_SC_DUPUN 0x0004 /* Duplicate unit number */
YX#define M_SC_ALONL 0x0008 /* Already online */
YX#define M_SC_STONL 0x0010 /* Still online */
YX#define M_SC_UNIGN 0x0011 /* Unload ignored */
YX#define M_SC_EOT 0x0020 /* EOT seen */
YX#define M_SC_ROVOL 0x0080 /* Read only volume */
YX
YX/*
YX * Invalid command subcodes
YX*/
YX#define M_SC_INVML 0x0000 /* Invalid message length */
YX
YX/*
YX * Data error subcodes
YX*/
YX#define M_SC_LGAP 0x0000 /* Long gap seen */
YX#define M_SC_UREAD 0x0007 /* Unrecoverable read err */
YX
YX/*
YX * Unit offline subcodes
YX*/
YX#define M_SC_UNKNO 0x0000 /* Unit unknown */
YX#define M_SC_NOVOL 0x0001 /* No volume (turned off) */
YX#define M_SC_INOPR 0x0002 /* Unit is inoperative */
YX#define M_SC_UDSBL 0x0008 /* Unit disabled */
YX#define M_SC_EXUSE 0x0010 /* Unit in use elsewhere */
YX#define M_SC_LOADE 0x0020 /* Loader error */
YX
YX/*
YX * Unit available subcodes
YX*/
YX#define M_SC_AVAIL 0x0000 /* Success */
YX
YX/*
YX * Write protect subcodes
YX*/
YX#define M_SC_DATL 0x0008 /* Data loss write protected */
YX#define M_SC_SOFTW 0x0080 /* Software write protected */
YX#define M_SC_HARDW 0x0100 /* Hardware write protected */
YX
YX/*
YX * Error Log message format codes
YX */
YX#define M_FM_CNTERR 0 /* Controller error */
YX#define M_FM_BUSADDR 1 /* Host memory access error */
YX#define M_FM_TAPETRN 5 /* Tape transfer error */
YX#define M_FM_STIERR 6 /* STI communication or command failure */
YX#define M_FM_STIDEL 7 /* STI drive error log */
YX#define M_FM_STIFEL 010 /* STI formatter error log */
YX
YX/*
YX * Error Log message flags
YX */
YX#define M_LF_SUCC 0x80 /* Operation successful */
YX#define M_LF_CONT 0x40 /* Operation continuing */
YX#define M_LF_SQNRS 0x01 /* Sequence number reset */
YX
YX/*
YX * Tape Format Flag Values
YX */
YX#define M_TF_800 0x01 /* NRZI 800 bpi */
YX#define M_TF_PE 0x02 /* Phase Encoded 1600 bpi */
YX#define M_TF_GCR 0x04 /* Group Code Recording 6250 bpi */
YX#define M_TF_BLK 0x08 /* Cartridge Block Mode */
YX
YX#endif /* _MSCP_COMMON_H_ */
YSHAR_EOF
Ychmod 644 '/usr/src/sys/pdp/mscp_common.h'
Yfi
Yif test -f '/usr/src/sys/pdpuba/tmscpdump.c'
Ythen
Y echo shar: "will not over-write existing file '/usr/src/sys/pdpuba/tmscpdump.c'"
Yelse
Ysed 's/^X//' << \SHAR_EOF > '/usr/src/sys/pdpuba/tmscpdump.c'
YX/*
YX * 1.1 (2.11BSD) 1995/12/14
YX *
YX * This routine was moved from the main TMSCP driver due to size problems.
YX * The driver could become over 8kb in size and would not fit within an
YX * overlay!
YX *
YX * Thought was given to simply deleting this routine altogether - who
YX * does crash dumps to tape (and the tmscp.c driver is the only one with
YX * a crash dump routine) but in the end the decision was made to retain
YX * the capability but move it to a separate file.
YX*/
YX
YX#include "tms.h"
YX#if NTMSCP > 0
YX
YX#include "param.h"
YX#include "buf.h"
YX#include "machine/seg.h"
YX#include "tmscpreg.h"
YX#include "pdp/tmscp.h"
YX#include "errno.h"
YX#include "map.h"
YX#include "uba.h"
YX#include "pdp/seg.h"
YX
YX#ifdef TMSCP_DUMP
YX#define DBSIZE 16
YX
YXextern memaddr tmscp[];
YXextern char *tmscpfatalerr;
YXextern struct tmscp_softc tmscp_softc[];
YX
YXtmsdump(dev)
YX dev_t dev;
YX{
YX register struct tmscpdevice *tmscpaddr;
YX register struct tmscp_softc *sc;
YX register struct mscp *mp;
YX daddr_t bn, dumpsize;
YX long paddr, maddr;
YX int unit = TMSUNIT(dev), count, ctlr = TMSCTLR(dev);
YX struct ubmap *ubp;
YX segm seg5;
YX
YX if (ctlr >= NTMSCP)
YX return (ENXIO);
YX sc = &tmscp_softc[ctlr];
YX tmscpaddr = sc->sc_addr;
YX if (tmscpaddr == NULL)
YX return(ENXIO);
YX
YX paddr = _iomap(tmscp[sc->sc_unit]);
YX if (ubmap) {
YX ubp = UBMAP;
YX ubp->ub_lo = loint(paddr);
YX ubp->ub_hi = hiint(paddr);
YX }
YX paddr += RINGBASE;
YX saveseg5(seg5);
YX mapseg5(tmscp[sc->sc_unit], MAPBUFDESC);
YX mp = sc->sc_com->tmscp_rsp;
YX sc->sc_com->tmscp_ca.ca_cmdint = sc->sc_com->tmscp_ca.ca_rspint = 0;
YX bzero(mp, 2 * sizeof (*mp));
YX
YX tmscpaddr->tmscpip = 0;
YX while ((tmscpaddr->tmscpsa & TMSCP_STEP1) == 0)
YX if(tmscpaddr->tmscpsa & TMSCP_ERR) return(EFAULT);
YX tmscpaddr->tmscpsa = TMSCP_ERR;
YX while ((tmscpaddr->tmscpsa & TMSCP_STEP2) == 0)
YX if(tmscpaddr->tmscpsa & TMSCP_ERR) return(EFAULT);
YX tmscpaddr->tmscpsa = loint(paddr);
YX while ((tmscpaddr->tmscpsa & TMSCP_STEP3) == 0)
YX if(tmscpaddr->tmscpsa & TMSCP_ERR) return(EFAULT);
YX tmscpaddr->tmscpsa = hiint(paddr);
YX while ((tmscpaddr->tmscpsa & TMSCP_STEP4) == 0)
YX if(tmscpaddr->tmscpsa & TMSCP_ERR) return(EFAULT);
YX tmscpaddr->tmscpsa = TMSCP_GO;
YX
YX tmsginit(sc, sc->sc_com->tmscp_ca.ca_rspdsc, mp, 0, 2, 0);
YX
YX if (tmscpcmd(M_OP_STCON, unit, sc) == 0) {
YX return(EFAULT);
YX }
YX sc->sc_com->tmscp_cmd[0].mscp_unit = unit;
YX if (tmscpcmd(M_OP_ONLIN, unit, sc) == 0) {
YX return(EFAULT);
YX }
YX
YX dumpsize = 8 * 1024L; /* XXX */
YX ubp = &UBMAP[1];
YX for (paddr = 0; dumpsize > 0; dumpsize -= count) {
YX count = MIN(dumpsize, DBSIZE);
YX bn = paddr >> PGSHIFT;
YX maddr = paddr;
YX if (ubmap) {
YX ubp->ub_lo = loint(paddr);
YX ubp->ub_hi = hiint(paddr);
YX maddr = (u_int)(1 << 13);
YX }
YX /* write it to the tape */
YX mp = &sc->sc_com->tmscp_rsp[1];
YX mp->mscp_lbn_l = loint(bn);
YX mp->mscp_lbn_h = hiint(bn);
YX mp->mscp_bytecnt = count * NBPG;
YX mp->mscp_buffer_l = loint(maddr);
YX mp->mscp_buffer_h = hiint(maddr);
YX if (tmscpcmd(M_OP_WRITE, unit, sc) == 0)
YX return(EIO);
YX paddr += (DBSIZE << PGSHIFT);
YX }
YX restorseg5(seg5);
YX return (0);
YX}
YX
YX/*
YX * Perform a standalone tmscp command. This routine is only used by tmscpdump.
YX */
YX
YXtmscpcmd(op, unit, sc)
YX int op;
YX int unit;
YX register struct tmscp_softc *sc;
YX{
YX int i;
YX register struct mscp *cmp, *rmp;
YX Trl *rlp;
YX
YX cmp = &sc->sc_com->tmscp_rsp[1];
YX rmp = &sc->sc_com->tmscp_rsp[0];
YX rlp = &sc->sc_com->tmscp_ca.ca_rspdsc[0];
YX
YX cmp->mscp_opcode = op;
YX cmp->mscp_unit = unit;
YX cmp->mscp_header.tmscp_msglen = mscp_msglen;
YX rmp->mscp_header.tmscp_msglen = mscp_msglen;
YX rlp[0].hsh |= TMSCP_OWN|TMSCP_INT;
YX rlp[1].hsh |= TMSCP_OWN|TMSCP_INT;
YX if (sc->sc_addr->tmscpsa&TMSCP_ERR)
YX printf(tmscpfatalerr, sc->sc_unit, unit, sc->sc_addr->tmscpsa);
YX i = sc->sc_addr->tmscpip;
YX
YX while ((rlp[1].hsh & TMSCP_INT) == 0)
YX ;
YX while ((rlp[0].hsh & TMSCP_INT) == 0)
YX ;
YX
YX sc->sc_com->tmscp_ca.ca_rspint = 0;
YX sc->sc_com->tmscp_ca.ca_cmdint = 0;
YX if (rmp->mscp_opcode != (op|M_OP_END) ||
YX (rmp->mscp_status&M_ST_MASK) != M_ST_SUCC)
YX {
YX printf("err: com %d opc 0x%x stat 0x%x\ndump ", op,
YX rmp->mscp_opcode, rmp->mscp_status);
YX return(0);
YX }
YX return(1);
YX}
YX#endif /* TMSCP_DUMP */
YX#endif /* NTMSCP */
YSHAR_EOF
Ychmod 644 '/usr/src/sys/pdpuba/tmscpdump.c'
Yfi
Yif test -f '/usr/src/sys/sys/ufs_syscalls2.c'
Ythen
Y echo shar: "will not over-write existing file '/usr/src/sys/sys/ufs_syscalls2.c'"
Yelse
Ysed 's/^X//' << \SHAR_EOF > '/usr/src/sys/sys/ufs_syscalls2.c'
YX/*
YX * @(#) ufs_syscalls2.c (2.11BSD) 1995/12/24
YX *
YX * ufs_syscalls was getting too large. New UFS related system calls are
YX * placed in this file.
YX*/
YX
YX#include "param.h"
YX#include "../machine/seg.h"
YX#include "user.h"
YX#include "inode.h"
YX#include "fs.h"
YX#include "namei.h"
YX#include "mount.h"
YX
YXstatfs()
YX {
YX register struct a
YX {
YX char *path;
YX struct statfs *buf;
YX } *uap = (struct a *)u.u_ap;
YX register struct inode *ip;
YX register struct nameidata *ndp = &u.u_nd;
YX struct mount *mp;
YX
YX ndp->ni_nameiop = LOOKUP|FOLLOW;
YX ndp->ni_segflg = UIO_USERSPACE;
YX ndp->ni_dirp = uap->path;
YX ip = namei(ndp);
YX if (!ip)
YX return(u.u_error);
YX mp = (struct mount *)((int)ip->i_fs - offsetof(struct mount, m_filsys));
YX irele(ip);
YX u.u_error = statfs1(mp, uap->buf);
YX return(u.u_error);
YX }
YX
YXfstatfs()
YX {
YX register struct a
YX {
YX int fd;
YX struct statfs *buf;
YX } *uap = (struct a *)u.u_ap;
YX register struct inode *ip;
YX struct mount *mp;
YX
YX ip = getinode(uap->fd);
YX if (!ip)
YX return(u.u_error);
YX mp = (struct mount *)((int)ip->i_fs - offsetof(struct mount, m_filsys));
YX u.u_error = statfs1(mp, uap->buf);
YX return(u.u_error);
YX }
YX
YXstatfs1(mp, sbp)
YX struct mount *mp;
YX struct statfs *sbp;
YX {
YX struct statfs sfs;
YX register struct statfs *sfsp;
YX struct xmount *xmp = (struct xmount *)SEG5;
YX struct fs *fs = &mp->m_filsys;
YX
YX sfsp = &sfs;
YX sfsp->f_type = MOUNT_UFS;
YX sfsp->f_bsize = MAXBSIZE;
YX sfsp->f_iosize = MAXBSIZE;
YX sfsp->f_blocks = fs->fs_fsize;
YX sfsp->f_bfree = fs->fs_tfree;
YX sfsp->f_bavail = fs->fs_tfree;
YX sfsp->f_files = (fs->fs_isize - 2) * INOPB;
YX sfsp->f_ffree = fs->fs_tinode;
YX
YX mapseg5(mp->m_extern, XMOUNTDESC);
YX bcopy(xmp->xm_mnton, sfsp->f_mntonname, MNAMELEN);
YX bcopy(xmp->xm_mntfrom, sfsp->f_mntfromname, MNAMELEN);
YX normalseg5();
YX sfsp->f_flags = mp->m_flags & MNT_VISFLAGMASK;
YX return(copyout(sfsp, sbp, sizeof (struct statfs)));
YX }
YX
YXgetfsstat()
YX {
YX register struct a
YX {
YX struct statfs *buf;
YX int bufsize;
YX u_int flags;
YX } *uap = (struct a *)u.u_ap;
YX register struct mount *mp;
YX caddr_t sfsp;
YX int count, maxcount, error;
YX
YX maxcount = uap->bufsize / sizeof (struct statfs);
YX sfsp = (caddr_t)uap->buf;
YX count = 0;
YX for (mp = mount; mp < &mount[NMOUNT]; mp++)
YX {
YX if (mp->m_inodp == NULL)
YX continue;
YX if (count < maxcount)
YX {
YX if (error = statfs1(mp, sfsp))
YX return(u.u_error = error);
YX sfsp += sizeof (struct statfs);
YX }
YX count++;
YX }
YX if (sfsp && count > maxcount)
YX u.u_r.r_val1 = maxcount;
YX else
YX u.u_r.r_val1 = count;
YX return(0);
YX }
YSHAR_EOF
Ychmod 644 '/usr/src/sys/sys/ufs_syscalls2.c'
Yfi
Yexit 0
Y# End of shell archive
SHAR_EOF
chmod 640 '/tmp/shar.283'
fi
exit 0
# End of shell archive