--- /dev/null
+#! /bin/sh
+# This is a shell archive. Remove anything before this line, then unpack
+# it by saving it into a file and typing "sh file". To overwrite existing
+# files, type "sh file -c". You can also feed this as standard input via
+# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
+# will see the following message at the end:
+# "End of archive 2 (of 3)."
+# Contents: di.c
+# Wrapped by root@seer on Thu Feb 24 10:15:51 2000
+PATH=/bin:/usr/bin:/usr/ucb ; export PATH
+if test -f 'di.c' -a "${1}" != "-c" ; then
+ echo shar: Will not clobber existing file \"'di.c'\"
+else
+echo shar: Extracting \"'di.c'\" \(97566 characters\)
+sed "s/^X//" >'di.c' <<'END_OF_FILE'
+X#ifndef lint
+Xstatic char di_c_sccsid [] =
+X"@(#)di.c 1.21";
+Xstatic char di_c_rcsid [] =
+X"$Id$";
+Xstatic char di_c_source [] =
+X"$Source$";
+Xstatic char copyright [] =
+X"Copyright 1994-1999 Brad Lanam, Walnut Creek, CA";
+X#endif
+X
+X/*
+X * di.c
+X *
+X * Copyright 1994-1999 Brad Lanam, Walnut Creek, CA
+X *
+X * Warning: Do not replace your systems 'df' command with this program.
+X * You will in all likelihood break your installation procedures.
+X *
+X * Usage: di -AafntwWx [file [...]]
+X * -A : print all fields (used for debugging)
+X * -a : print all mounted devices; normally, those
+X * with 0 total blocks are not printed. e.g.
+X * /dev/proc, /dev/fd.
+X * -d x : size to print blocks in (p, k, m, g, <n>)
+X * -f x : use format string <x>
+X * -i x : ignore filesystem type(s) x, where x is a comma
+X * separated list.
+X * -I x : include only filesystem type(s) x, where x is a
+X * separated list.
+X * -l : local filesystems only
+X * -n : don't print header
+X * -s t : sort type
+X * -t : print totals
+X * -w n : use <n> for the block print width (default 8).
+X * -W n : use <n> for the inode print width (default 7).
+X * -x n : debug level <n>
+X *
+X * All values are reported in K (1024 bytes).
+X *
+X * Sort types (by name is default):
+X * n - none (mount order)
+X * s - special
+X * r - reverse sort
+X *
+X * Format string values:
+X * m - mount point
+X * M - mount point, full length
+X * b - total kbytes
+X * B - total kbytes available for use by the user.
+X * [ (tot - (free - avail) ]
+X * u - kbytes used (actual number of kbytes used) [ (tot - free) ]
+X * c - calculated number of kbytes used [ (tot - avail) ]
+X * f - kbytes free
+X * v - kbytes available
+X * p - percentage not available for use.
+X * (number of blocks not available for use / total disk space)
+X * [ (tot - avail) / tot ]
+X * 1 - percentage used.
+X * (actual number of blocks used / total disk space)
+X * [ (tot - free) / tot ]
+X * 2 - percentage of user-available space in use (bsd style).
+X * Note that values over 100% are possible.
+X * (actual number of blocks used / disk space available to user)
+X * [ (tot - free) / (tot - (free - avail)) ]
+X * i - total i-nodes (files)
+X * U - used i-nodes
+X * F - free i-nodes
+X * P - percent i-nodes used [ (tot - avail) / tot ]
+X * s - filesystem name (special)
+X * S - filesystem name (special), full length
+X * t - disk partition type
+X * T - disk partition type (full length)
+X * I - mount time
+X * O - mount options.
+X *
+X * System V.4 `/usr/bin/df -v` Has format: msbuf1 (w/-d512 option: 512 byte blocks)
+X * System V.4 `/usr/bin/df -k` Has format: sbcvpm
+X * System V.4 `/usr/ucb/df` Has format: sbuv2m
+X *
+X * The default format string for this program is: smbuvpT
+X *
+X * The environment variable "DIFMT" may be set to the desired format
+X * string.
+X *
+X * Note that for filesystems that do not have (S512K fs) or systems (SysV.3)
+X * that do not report available blocks, the number of available blocks is
+X * equal to the number of free blocks.
+X *
+X * HISTORY:
+X * 24 feb 2000 bll
+X * Updated for BeOS. This required changes to support c++
+X * compilation (ansi style functions). Fixes for linux.
+X * 17 dec 99 bll
+X * Added sys/fs_types.h (Digital Unix (tru64)).
+X * 3 jan 99 bll
+X * Finalize changes for metaconfig.
+X * Always get stat() for disk device.
+X * Remove duplicate disks from display.
+X * Add NetBSD, Unicos, IRIX changes
+X * 8 sep 97 bll
+X * Solaris large file version; AIX typo fix
+X * 15 aug 95 bll
+X * Ignore will check the file system type beforehand if possible.
+X * Fixed local mount stuff for osf1.
+X * 9 aug 95 bll
+X * Changed totals to use double; the totals can now be displayed with
+X * any wanted block size; sizes > one k have a single decimal point.
+X * -d option specifies block size.
+X * -l option for local file systems only.
+X * 7 aug 95 bll
+X * convex fix.
+X * 29 jul 95 bll
+X * Fixed bsdi variants. The fragment size wasn't being supported.
+X * 22 jul 95 bll
+X * fix problem with display widths in conjunction with ignore/include
+X * 20 feb 95 bll
+X * added ignore/include file system type lists.
+X * 8 jan 95 bll
+X * Added FreeBsd 2.x
+X * 6 dec 94 bll
+X * sco nfs 'nothing' fix.
+X * 28 nov 94 bll
+X * bsdi [bag@clipper.cs.kiev.ua (Andrey Blochintsev)]
+X * 24 nov 94 bll
+X * Added FreeBsd - like OSF/1, but w/o nice mount name table.
+X * 1 may 94 bll
+X * removed ill conceived mount options stuff. Added AIX
+X * (Erik O'Shaughnessy eriko@risc.austin.ibm.com).
+X * Added coherent.
+X * 9 apr 94 bll
+X * T format from Bill Davidsen. SunOS file system type.
+X * mount options.
+X * 7 apr 94 bll
+X * cdrom under solaris returning -1 in addition to -2.
+X * Changed the test to test for any negative value.
+X * 5 apr 94 pm
+X * Filesystem type info, and whether its read-write, readonly
+X * etc is in the mntent structure. Added code to support it.
+X * [Pat Myrto <pat@rwing.uucp>]
+X * 25 mar 94 bll
+X * sun had f_bfree instead of f_bavail!
+X * Xenix, linux.
+X * -w, -W options, -B option, fixed width for -f M, -f S.
+X * Usage. Allow other characters in format string.
+X * 4 mar 94 bll
+X * -f B, bug fixes. bcopy.
+X * Solaris cdrom reports total, not free or avail.
+X * Allow command line specification of file names.
+X * 3 mar 94 bll
+X * support for OSF/1 and ULTRIX, -F, -f M, -f S
+X * [mogul@wrl.dec.com (Jeffrey Mogul)]
+X * 3 mar 94 bll
+X * Allow command line specification of filename (s).
+X * Sort output. Test of nonexistent return code removed.
+X * 1 mar 94 bll
+X * # of inodes can be -1L if unreportable.
+X * [jjb@jagware.bcc.com (J.J.Bailey)]
+X * [Mark Neale <mark@edscom.demon.co.uk>]
+X * getDiskInfo () returning garbage
+X * [costales@ICSI.Berkeley.EDU (Bryan Costales)]
+X * [Mark Neale <mark@edscom.demon.co.uk>]
+X * pyramid #ifdefs
+X * [vogelke@c-17igp.wpafb.af.mil (Contr Karl Vogel)]
+X * name must be maxpathlen
+X * [Mark Neale <mark@edscom.demon.co.uk>]
+X * error prints/compile warnings.
+X * [Mark Neale <mark@edscom.demon.co.uk>]
+X *
+X */
+X
+X#include "config.h"
+X
+X#include <stdio.h>
+X#include <ctype.h>
+X#include <errno.h>
+X#if defined (I_STDLIB)
+X# include <stdlib.h>
+X#endif
+X#if defined (I_SYS_TYPES)
+X# include <sys/types.h>
+X#endif
+X#if defined (I_LIMITS)
+X# include <limits.h>
+X#endif
+X#if defined (I_STRING)
+X# include <string.h>
+X#else
+X# include <strings.h>
+X#endif
+X#if defined (I_MEMORY)
+X# include <memory.h>
+X#endif
+X#if defined (I_MALLOC)
+X# include <malloc.h>
+X#endif
+X#if defined (I_UNISTD)
+X# include <unistd.h>
+X#endif
+X#if defined (I_TIME)
+X# include <time.h>
+X#endif
+X#if defined (I_SYS_TIME)
+X# include <sys/time.h>
+X#endif
+X#if defined (I_SYS_STAT)
+X# include <sys/stat.h>
+X#endif
+X#if defined (I_SYS_PARAM)
+X# include <sys/param.h>
+X#endif
+X
+X#if defined (I_SYS_MNTTAB)
+X# include <sys/mnttab.h>
+X#endif
+X#if defined (I_MNTTAB)
+X# include <mnttab.h>
+X#endif
+X#if defined (I_MNTENT)
+X# include <mntent.h>
+X#endif
+X#if defined (I_SYS_MNTENT)
+X# include <sys/mntent.h>
+X#endif
+X#if defined (I_SYS_MOUNT)
+X# include <sys/mount.h>
+X#endif
+X#if defined (I_SYS_FSTYPES)
+X# include <sys/fstypes.h>
+X#endif
+X#if defined (I_SYS_FS_TYPES)
+X# include <sys/fs_types.h>
+X#endif
+X#if defined (I_SYS_MNTCTL)
+X# include <sys/mntctl.h>
+X#endif
+X#if defined (I_SYS_VMOUNT)
+X# include <sys/vmount.h>
+X#endif
+X#if defined (I_SYS_STATFS) && ! defined (I_SYS_STATVFS)
+X# include <sys/statfs.h>
+X#endif
+X#if defined (I_FSHELP)
+X# include <fshelp.h>
+X#endif
+X#if defined (I_SYS_STATVFS)
+X# include <sys/statvfs.h>
+X#endif
+X#if defined (I_SYS_FSTYP)
+X# include <sys/fstyp.h>
+X# define DI_TYPE_LEN FSTYPSZ
+X#endif
+X#if defined (I_SYS_VFS)
+X# include <sys/vfs.h>
+X#endif
+X#if defined (I_SYS_VFSTAB)
+X# include <sys/vfstab.h>
+X# if ! defined (DI_TYPE_LEN)
+X# define DI_TYPE_LEN FSTYPSZ
+X# endif
+X#endif
+X#if defined (I_FSHELP)
+X# include <fshelp.h>
+X#endif
+X
+X#if defined (I_WINDOWS)
+X# include <windows.h> /* windows */
+X#endif
+X#if defined (I_KERNFSINFO)
+X# include <kernel/fs_info.h>
+X#endif
+X#if defined (I_STOR_DIRECTORY)
+X# include <storage/Directory.h>
+X#endif
+X#if defined (I_STOR_ENTRY)
+X# include <storage/Entry.h>
+X#endif
+X/*#if defined (I_STOR_NODE)
+X# include <storage/Node.h>
+X#endif */
+X#if defined (I_STOR_PATH)
+X# include <storage/Path.h>
+X#endif
+X
+X#if ! defined (HAS_MEMCPY) && ! defined (memcpy)
+X# if ! defined (HAS_BCOPY)
+X error No memcpy/bcopy available.
+X# else
+X# define memcpy(dst, src, cnt) (bcopy((src), (dst), (cnt)), dst)
+X# endif
+X#endif
+X
+X#if ! defined (MAXPATHLEN)
+X# if defined (_POSIX_PATH_MAX)
+X# define MAXPATHLEN _POSIX_PATH_MAX
+X# else
+X# if defined (PATH_MAX)
+X# define MAXPATHLEN PATH_MAX
+X# endif
+X# if defined (LPNMAX)
+X# define MAXPATHLEN LPNMAX
+X# endif
+X# endif
+X#endif
+X
+X#if ! defined (DI_TYPE_LEN)
+X# define DI_TYPE_LEN 16
+X#endif
+X
+X#define DI_FSMAGIC 5 /* base AIX configuration has 5 file systems */
+X
+X#if defined (HAS_STATFS_SYSV3) && ! defined (HAS_STATVFS) && \
+X ! defined (HAS_GETMNTINFO) && ! defined (HAS_GETMNT) /* SYSV.3 */
+X# if defined (Ubsize) && Ubsize != ""
+X# define UBSIZE Ubsize
+X# endif
+X# if ! defined (UBSIZE)
+X# define UBSIZE 512
+X# endif
+X#endif
+X
+X#if (defined (HAS_GETMNTENT) || defined (HAS_STATFS_BSD) || \
+X defined (HAS_STATFS_SYSV3)) && ! defined (HAS_GETMNTINFO) && \
+X ! defined (HAS_GETMNT)
+X# if defined (MOUNTED)
+X# define DI_MOUNT_FILE MOUNTED
+X# else
+X# if defined (MNTTAB)
+X# define DI_MOUNT_FILE MNTTAB
+X# else
+X# define DI_MOUNT_FILE "/etc/mnttab"
+X# endif
+X# endif
+X#endif
+X
+X#if ! defined (HAS_MEMSET) && ! defined (memset)
+X# if ! defined (HAS_BZERO)
+X error No memset/bzero available.
+X# else
+X# define memset(s,c,n) (bzero ((s), (n)), s)
+X# endif
+X#endif
+X
+X#if defined (NEED_GETENV_DEF)
+X extern char *getenv _((char *));
+X#endif
+X
+X#if defined (NEED_STATFS_DEFS)
+X extern int statfs _((char *, struct statfs *));
+X#endif
+X
+X#if defined (NEED_ERRNO_DEFS)
+Xextern int errno;
+X#endif
+X
+X#if (defined (_LARGEFILE_SOURCE) || defined (_LARGEFILE64_SOURCE)) && \
+X _FILE_OFFSET_BITS == 64
+X# define HAS_64BIT_STATFS_FLDS 1
+X#endif
+X
+X#if defined (HAS_64BIT_STATFS_FLDS)
+Xtypedef unsigned long long _fs_size_t;
+Xtypedef long long _s_fs_size_t;
+X#else
+Xtypedef unsigned long _fs_size_t;
+Xtypedef long _s_fs_size_t;
+X#endif
+X
+X#if ! defined (HAS_OPTIND)
+X extern int optind;
+X extern char *optarg;
+X#endif
+X
+X/* end of system specific includes/configurations */
+X
+X#if ! defined (TRUE)
+X# define TRUE 1
+X#endif
+X#if ! defined (FALSE)
+X# define FALSE 0
+X#endif
+X
+X#define DI_F_ALL 0x00000001
+X#define DI_F_LOCAL_ONLY 0x00000002
+X#define DI_F_TOTAL 0x00000010
+X#define DI_F_NO_HEADER 0x00000020
+X#define DI_F_DEBUG_HDR 0x00000040
+X
+X /* mount information */
+X#define DI_FMT_MOUNT 'm'
+X#define DI_FMT_MOUNT_FULL 'M'
+X#define DI_FMT_SPECIAL 's'
+X#define DI_FMT_SPECIAL_FULL 'S'
+X#define DI_FMT_TYPE 't'
+X#define DI_FMT_TYPE_FULL 'T'
+X
+X /* disk information */
+X#define DI_FMT_BTOT 'b'
+X#define DI_FMT_BTOT_AVAIL 'B'
+X#define DI_FMT_BUSED 'u'
+X#define DI_FMT_BCUSED 'c'
+X#define DI_FMT_BFREE 'f'
+X#define DI_FMT_BAVAIL 'v'
+X#define DI_FMT_BPERC_AVAIL 'p'
+X#define DI_FMT_BPERC_FREE '1'
+X#define DI_FMT_BPERC_BSD '2'
+X#define DI_FMT_ITOT 'i'
+X#define DI_FMT_IUSED 'U'
+X#define DI_FMT_IFREE 'F'
+X#define DI_FMT_IPERC 'P'
+X#define DI_FMT_MOUNT_TIME 'I'
+X#define DI_FMT_MOUNT_OPTIONS 'O'
+X
+X#define DI_IGNORE 0
+X#define DI_OK 1
+X#define DI_BAD 2
+X
+X#define DI_SORT_NONE 0
+X#define DI_SORT_NAME 1
+X#define DI_SORT_SPECIAL 2
+X
+X#define DI_SORT_ASCENDING 1
+X#define DI_SORT_DESCENDING -1
+X
+X#define DI_UNKNOWN_DEV -1L
+X#define DI_LIST_SEP ","
+X
+X#define DI_ALL_FORMAT "MTS\n\tIO\n\tbuf1\n\tbcvp\n\tBuv2\n\tiUFP"
+X
+X#define DI_HALF_K 512.0
+X#define DI_ONE_K 1024.0
+X#define DI_ONE_MEG 1048576.0
+X#define DI_ONE_GIG 1073241824.0
+X
+X#if ! defined (MAXPATHLEN)
+X# define MAXPATHLEN 255
+X#endif
+X#define DI_SPEC_NAME_LEN MAXPATHLEN
+X#define DI_OPT_LEN MAXPATHLEN
+X#define DI_MNT_TIME_LEN 24
+X
+X#define DI_RETRY_COUNT 5
+X#define DI_MAX_REMOTE_TYPES 20
+X
+X /* you may want to change some of these values. Be sure to change all */
+X /* related entries. */
+X/* #define DI_DEFAULT_FORMAT "mbuvpiUFP" */
+X#if ! defined (DI_DEFAULT_FORMAT)
+X# define DI_DEFAULT_FORMAT "smbuvpT"
+X#endif
+X#if defined (HAS_MNT_TIME)
+X# define DI_DEF_MOUNT_FORMAT "MSTIO"
+X#else
+X# define DI_DEF_MOUNT_FORMAT "MSTO"
+X#endif
+X#define DI_PERC_FMT "%3.0f%% "
+X#define DI_PERC_LBL_FMT "%5s"
+X#define DI_NAME_LEN MAXPATHLEN
+X#define DI_FSTYPE_FMT "%-7.7s"
+X#define DI_MOUNT_FMT "%-15.15s"
+X#define DI_SPEC_FMT "%-18.18s"
+X
+X#define DI_UNKNOWN_FSTYPE "Unknown fstyp %.2d"
+X
+Xtypedef unsigned long _ulong;
+Xtypedef int (*DI_SORT_FUNC) _((char *, char *));
+X
+Xtypedef struct
+X{
+X double totalBlocks;
+X double freeBlocks;
+X double availBlocks;
+X _fs_size_t totalInodes;
+X _fs_size_t freeInodes;
+X _fs_size_t availInodes;
+X _ulong st_dev; /* disk device number */
+X _ulong sp_dev; /* special device number*/
+X _ulong sp_rdev; /* special rdev # */
+X char printFlag; /* do we want to print */
+X /* this entry? */
+X char isLocal; /* is this mount point */
+X /* local? */
+X char name [DI_NAME_LEN + 1]; /* mount point */
+X char special [DI_SPEC_NAME_LEN + 1]; /* special device name */
+X char fsType [DI_TYPE_LEN + 1]; /* type of file system */
+X char options [DI_OPT_LEN + 1];
+X char mountTime [DI_MNT_TIME_LEN + 1];
+X} DiskInfo;
+X
+Xstatic DiskInfo *diskInfo = { (DiskInfo *) NULL };
+Xstatic int diCount = { 0 };
+Xstatic int debug = { 0 };
+Xstatic _ulong flags = { 0 };
+Xstatic int sortType = { DI_SORT_NAME };
+Xstatic int sortOrder = { DI_SORT_ASCENDING };
+Xstatic char *formatString = { DI_DEFAULT_FORMAT };
+Xstatic char mountFormat [20];
+X static char specialFormat [20];
+Xstatic char typeFormat [20];
+Xstatic char optFormat [20];
+Xstatic char mTimeFormat [20];
+Xstatic int width = { 8 };
+Xstatic int inodeWidth = { 7 };
+Xstatic char blockFormat [20];
+Xstatic char blockLabelFormat [20];
+Xstatic char inodeFormat [20];
+Xstatic char inodeLabelFormat [20];
+Xstatic char **ignoreList = { (char **) NULL };
+Xstatic char **includeList = { (char **) NULL };
+Xstatic double dispBlockSize = { DI_ONE_MEG };
+Xstatic int remoteFileSystemCount = { 0 };
+Xstatic char remoteFileSystemTypes [DI_MAX_REMOTE_TYPES][DI_TYPE_LEN];
+X
+X
+Xstatic void cleanup _((void));
+Xstatic void printDiskInfo _((void));
+Xstatic void printInfo _((DiskInfo *));
+Xstatic void addTotals _((DiskInfo *, DiskInfo *));
+Xstatic void printTitle _((void));
+Xstatic void printPerc _((double, double, char *));
+Xstatic char *Realloc _((char *, long));
+Xstatic void sortArray _((char *, int, int, DI_SORT_FUNC));
+Xstatic int diCompare _((char *, char *));
+Xstatic void getDiskStatInfo _((void));
+Xstatic void getDiskSpecialInfo _((void));
+Xstatic void printFileInfo _((int, int, char *[]));
+Xstatic void checkDiskInfo _((void));
+Xstatic void usage _((void));
+Xstatic void processArgs _((int, char *[]));
+Xstatic void parseList _((char ***, char *));
+Xstatic void checkIgnoreList _((DiskInfo *));
+Xstatic void checkIncludeList _((DiskInfo *));
+X
+Xstatic int getDiskEntries _((void));
+Xstatic void getDiskInfo _((void));
+X
+Xint
+X#if defined (CAN_PROTOTYPE)
+Xmain (int argc, char *argv [])
+X#else
+Xmain (argc, argv)
+X int argc;
+X char *argv [];
+X#endif
+X{
+X char *ptr;
+X
+X
+X ptr = argv [0] + strlen (argv [0]) - 2;
+X if (memcmp (ptr, MPROG, 2) == 0)
+X {
+X formatString = DI_DEF_MOUNT_FORMAT;
+X }
+X else /* don't use DIFMT env var if running mi. */
+X {
+X if ((ptr = getenv ("DIFMT")) != (char *) NULL)
+X {
+X formatString = ptr;
+X }
+X }
+X
+X processArgs (argc, argv);
+X if (debug > 0)
+X {
+X printf ("di ver $Revision$\n");
+X }
+X
+X if (getDiskEntries () < 0)
+X {
+X cleanup ();
+X exit (1);
+X }
+X
+X getDiskInfo ();
+X getDiskSpecialInfo ();
+X checkDiskInfo ();
+X if (optind < argc)
+X {
+X getDiskStatInfo ();
+X printFileInfo (optind, argc, argv);
+X }
+X else
+X {
+X printDiskInfo ();
+X }
+X
+X cleanup ();
+X exit (0);
+X}
+X
+X/*
+X * cleanup
+X *
+X * free up allocated memory
+X *
+X */
+X
+Xstatic void
+X#if defined (CAN_PROTOTYPE)
+Xcleanup (void)
+X#else
+Xcleanup ()
+X#endif
+X{
+X char **lptr;
+X
+X
+X if (diskInfo != (DiskInfo *) NULL)
+X {
+X free ((char *) diskInfo);
+X }
+X
+X if (ignoreList != (char **) NULL)
+X {
+X lptr = ignoreList;
+X while (*lptr != (char *) NULL)
+X {
+X free ((char *) *lptr);
+X ++lptr;
+X }
+X free ((char *) ignoreList);
+X }
+X
+X if (includeList != (char **) NULL)
+X {
+X lptr = includeList;
+X while (*lptr != (char *) NULL)
+X {
+X free ((char *) *lptr);
+X ++lptr;
+X }
+X free ((char *) includeList);
+X }
+X}
+X
+X/*
+X * printDiskInfo
+X *
+X * Print out the disk information table.
+X * Loops through all mounted disks, prints and calculates totals.
+X *
+X */
+X
+Xstatic void
+X#if defined (CAN_PROTOTYPE)
+XprintDiskInfo (void)
+X#else
+XprintDiskInfo ()
+X#endif
+X{
+X int i;
+X DiskInfo totals;
+X
+X
+X memset ((char *) &totals, '\0', sizeof (DiskInfo));
+X strcpy (totals.name, "Total");
+X totals.printFlag = DI_OK;
+X
+X if ((flags & DI_F_NO_HEADER) != DI_F_NO_HEADER)
+X {
+X printTitle ();
+X }
+X
+X if (sortType != DI_SORT_NONE)
+X {
+X sortArray ((char *) diskInfo, sizeof (DiskInfo), diCount, diCompare);
+X }
+X
+X for (i = 0; i < diCount; ++i)
+X {
+X if (( (flags & DI_F_ALL) == DI_F_ALL &&
+X diskInfo [i].printFlag != DI_BAD) ||
+X diskInfo [i].printFlag == DI_OK)
+X {
+X printInfo (&diskInfo [i]);
+X addTotals (&diskInfo [i], &totals);
+X }
+X }
+X
+X if ((flags & DI_F_TOTAL) == DI_F_TOTAL &&
+X (flags & DI_F_NO_HEADER) != DI_F_NO_HEADER)
+X {
+X printInfo (&totals);
+X }
+X}
+X
+X/*
+X * printInfo
+X *
+X * Print the information for a single partition. Loop through the
+X * format string and print the particular items wanted.
+X *
+X */
+X
+Xstatic void
+X#if defined (CAN_PROTOTYPE)
+XprintInfo (DiskInfo *diskInfo)
+X#else
+XprintInfo (diskInfo)
+X DiskInfo *diskInfo;
+X#endif
+X{
+X double used;
+X double totAvail;
+X char *ptr;
+X int valid;
+X
+X
+X ptr = formatString;
+X while (*ptr)
+X {
+X valid = TRUE;
+X
+X switch (*ptr)
+X {
+X case DI_FMT_MOUNT:
+X {
+X printf (DI_MOUNT_FMT, diskInfo->name);
+X break;
+X }
+X
+X case DI_FMT_MOUNT_FULL:
+X {
+X printf (mountFormat, diskInfo->name);
+X break;
+X }
+X
+X case DI_FMT_BTOT:
+X {
+X printf (blockFormat, diskInfo->totalBlocks);
+X break;
+X }
+X
+X case DI_FMT_BTOT_AVAIL:
+X {
+X printf (blockFormat, diskInfo->totalBlocks -
+X (diskInfo->freeBlocks - diskInfo->availBlocks));
+X break;
+X }
+X
+X case DI_FMT_BUSED:
+X {
+X printf (blockFormat, diskInfo->totalBlocks -
+X diskInfo->freeBlocks);
+X break;
+X }
+X
+X case DI_FMT_BCUSED:
+X {
+X printf (blockFormat, diskInfo->totalBlocks - diskInfo->availBlocks);
+X break;
+X }
+X
+X case DI_FMT_BFREE:
+X {
+X printf (blockFormat, diskInfo->freeBlocks);
+X break;
+X }
+X
+X case DI_FMT_BAVAIL:
+X {
+X printf (blockFormat, diskInfo->availBlocks);
+X break;
+X }
+X
+X case DI_FMT_BPERC_AVAIL:
+X {
+X used = diskInfo->totalBlocks - diskInfo->availBlocks;
+X totAvail = diskInfo->totalBlocks;
+X printPerc (used, totAvail, DI_PERC_FMT);
+X break;
+X }
+X
+X case DI_FMT_BPERC_FREE:
+X {
+X used = diskInfo->totalBlocks - diskInfo->freeBlocks;
+X totAvail = diskInfo->totalBlocks;
+X printPerc (used, totAvail, DI_PERC_FMT);
+X break;
+X }
+X
+X case DI_FMT_BPERC_BSD:
+X {
+X used = diskInfo->totalBlocks - diskInfo->freeBlocks;
+X totAvail = diskInfo->totalBlocks -
+X (diskInfo->freeBlocks - diskInfo->availBlocks);
+X printPerc (used, totAvail, DI_PERC_FMT);
+X break;
+X }
+X
+X case DI_FMT_ITOT:
+X {
+X printf (inodeFormat, diskInfo->totalInodes);
+X break;
+X }
+X
+X case DI_FMT_IUSED:
+X {
+X printf (inodeFormat, diskInfo->totalInodes - diskInfo->freeInodes);
+X break;
+X }
+X
+X case DI_FMT_IFREE:
+X {
+X printf (inodeFormat, diskInfo->freeInodes);
+X break;
+X }
+X
+X case DI_FMT_IPERC:
+X {
+X used = diskInfo->totalInodes - diskInfo->availInodes;
+X totAvail = diskInfo->totalInodes;
+X printPerc (used, totAvail, DI_PERC_FMT);
+X break;
+X }
+X
+X case DI_FMT_SPECIAL:
+X {
+X printf (DI_SPEC_FMT, diskInfo->special);
+X break;
+X }
+X
+X case DI_FMT_SPECIAL_FULL:
+X {
+X printf (specialFormat, diskInfo->special);
+X break;
+X }
+X
+X case DI_FMT_TYPE:
+X {
+X printf (DI_FSTYPE_FMT, diskInfo->fsType);
+X break;
+X }
+X
+X case DI_FMT_TYPE_FULL:
+X {
+X printf (typeFormat, diskInfo->fsType);
+X break;
+X }
+X
+X case DI_FMT_MOUNT_OPTIONS:
+X {
+X printf (optFormat, diskInfo->options);
+X break;
+X }
+X
+X case DI_FMT_MOUNT_TIME:
+X {
+X#if defined (HAS_MNT_TIME)
+X printf (mTimeFormat, diskInfo->mountTime);
+X#endif
+X break;
+X }
+X
+X default:
+X {
+X printf ("%c", *ptr);
+X valid = FALSE;
+X break;
+X }
+X }
+X
+X ++ptr;
+X if (*ptr && valid)
+X {
+X printf (" ");
+X }
+X }
+X
+X printf ("\n");
+X}
+X
+X/*
+X * addTotals
+X *
+X * Add up the totals for the blocks/inodes
+X *
+X */
+X
+Xstatic void
+X#if defined (CAN_PROTOTYPE)
+XaddTotals (DiskInfo *diskInfo, DiskInfo *totals)
+X#else
+XaddTotals (diskInfo, totals)
+X DiskInfo *diskInfo;
+X DiskInfo *totals;
+X#endif
+X{
+X totals->totalBlocks += diskInfo->totalBlocks;
+X totals->freeBlocks += diskInfo->freeBlocks;
+X totals->availBlocks += diskInfo->availBlocks;
+X totals->totalInodes += diskInfo->totalInodes;
+X totals->freeInodes += diskInfo->freeInodes;
+X totals->availInodes += diskInfo->availInodes;
+X}
+X
+X/*
+X * printTitle
+X *
+X * Loop through the format string and print the appropriate headings.
+X *
+X */
+X
+Xstatic void
+X#if defined (CAN_PROTOTYPE)
+XprintTitle (void)
+X#else
+XprintTitle ()
+X#endif
+X{
+X char *ptr;
+X int valid;
+X char tbuff [20];
+X
+X if ((flags & DI_F_DEBUG_HDR) == DI_F_DEBUG_HDR)
+X {
+X printf ("di ver $Revision$ Default Format: %s\n",
+X DI_DEFAULT_FORMAT);
+X }
+X
+X ptr = formatString;
+X
+X while (*ptr)
+X {
+X valid = TRUE;
+X
+X switch (*ptr)
+X {
+X case DI_FMT_MOUNT:
+X {
+X printf (DI_MOUNT_FMT, "Mount");
+X break;
+X }
+X
+X case DI_FMT_MOUNT_FULL:
+X {
+X printf (mountFormat, "Mount");
+X break;
+X }
+X
+X case DI_FMT_BTOT:
+X case DI_FMT_BTOT_AVAIL:
+X {
+X if (dispBlockSize == DI_ONE_K)
+X {
+X printf (blockLabelFormat, "Kbytes");
+X }
+X else if (dispBlockSize == DI_ONE_MEG)
+X {
+X printf (blockLabelFormat, " Megs");
+X }
+X else if (dispBlockSize == DI_ONE_GIG)
+X {
+X printf (blockLabelFormat, " Gigs");
+X }
+X else if (dispBlockSize == DI_HALF_K)
+X {
+X printf (blockLabelFormat, " 512b");
+X }
+X else
+X {
+X sprintf (tbuff, "%6.0f", dispBlockSize);
+X printf (blockLabelFormat, tbuff);
+X }
+X break;
+X }
+X
+X case DI_FMT_BUSED:
+X case DI_FMT_BCUSED:
+X {
+X printf (blockLabelFormat, "Used");
+X break;
+X }
+X
+X case DI_FMT_BFREE:
+X {
+X printf (blockLabelFormat, "Free");
+X break;
+X }
+X
+X case DI_FMT_BAVAIL:
+X {
+X printf (blockLabelFormat, "Avail");
+X break;
+X }
+X
+X case DI_FMT_BPERC_AVAIL:
+X case DI_FMT_BPERC_FREE:
+X case DI_FMT_BPERC_BSD:
+X {
+X printf (DI_PERC_LBL_FMT, "%used");
+X break;
+X }
+X
+X case DI_FMT_ITOT:
+X {
+X printf (inodeLabelFormat, "Inodes");
+X break;
+X }
+X
+X case DI_FMT_IUSED:
+X {
+X printf (inodeLabelFormat, "Used");
+X break;
+X }
+X
+X case DI_FMT_IFREE:
+X {
+X printf (inodeLabelFormat, "Free");
+X break;
+X }
+X
+X case DI_FMT_IPERC:
+X {
+X printf (DI_PERC_LBL_FMT, "%used");
+X break;
+X }
+X
+X case DI_FMT_SPECIAL:
+X {
+X printf (DI_SPEC_FMT, "Filesystem");
+X break;
+X }
+X
+X case DI_FMT_SPECIAL_FULL:
+X {
+X printf (specialFormat, "Filesystem");
+X break;
+X }
+X
+X case DI_FMT_TYPE:
+X {
+X printf (DI_FSTYPE_FMT, "fsType");
+X break;
+X }
+X
+X case DI_FMT_TYPE_FULL:
+X {
+X printf (typeFormat, "fs Type");
+X break;
+X }
+X
+X case DI_FMT_MOUNT_OPTIONS:
+X {
+X printf (optFormat, "Options");
+X break;
+X }
+X
+X case DI_FMT_MOUNT_TIME:
+X {
+X#if defined (HAS_MNT_TIME)
+X printf (mTimeFormat, "Mount Time");
+X#endif
+X break;
+X }
+X
+X default:
+X {
+X printf ("%c", *ptr);
+X valid = FALSE;
+X break;
+X }
+X }
+X
+X ++ptr;
+X if (*ptr && valid)
+X {
+X printf (" ");
+X }
+X }
+X
+X printf ("\n");
+X}
+X
+X/*
+X * printPerc
+X *
+X * Calculate and print a percentage using the values and format passed.
+X *
+X */
+X
+Xstatic void
+X#if defined (CAN_PROTOTYPE)
+XprintPerc (double used, double totAvail, char *format)
+X#else
+XprintPerc (used, totAvail, format)
+X double used;
+X double totAvail;
+X char *format;
+X#endif
+X{
+X double perc;
+X
+X
+X if (totAvail > 0.0)
+X {
+X perc = used / totAvail;
+X perc *= 100.0;
+X }
+X else
+X {
+X perc = 0.0;
+X }
+X printf (format, perc);
+X}
+X
+X
+X/*
+X * Realloc
+X *
+X * portable realloc
+X *
+X */
+X
+Xstatic char *
+X#if defined (CAN_PROTOTYPE)
+XRealloc (char *ptr, long size)
+X#else
+XRealloc (ptr, size)
+X char *ptr;
+X long size;
+X#endif
+X{
+X if (ptr == (char *) NULL)
+X {
+X ptr = (char *) malloc (size);
+X }
+X else
+X {
+X ptr = (char *) realloc (ptr, size);
+X }
+X
+X return ptr;
+X}
+X
+X
+Xstatic void
+X#if defined (CAN_PROTOTYPE)
+XprintFileInfo (int optind, int argc, char *argv [])
+X#else
+XprintFileInfo (optind, argc, argv)
+X int optind;
+X int argc;
+X char *argv [];
+X#endif
+X{
+X int i;
+X int j;
+X struct stat statBuf;
+X DiskInfo totals;
+X
+X
+X memset ((char *) &totals, '\0', sizeof (DiskInfo));
+X strcpy (totals.name, "Total");
+X totals.printFlag = DI_OK;
+X
+X if ((flags & DI_F_NO_HEADER) != DI_F_NO_HEADER)
+X {
+X printTitle ();
+X }
+X
+X for (i = optind; i < argc; ++i)
+X {
+X if (stat (argv [i], &statBuf) == 0)
+X {
+X for (j = 0; j < diCount; ++j)
+X {
+X if (diskInfo [j].printFlag != DI_BAD &&
+X diskInfo [j].st_dev != DI_UNKNOWN_DEV &&
+X (_ulong) statBuf.st_dev == diskInfo [j].st_dev)
+X {
+X printInfo (&diskInfo [j]);
+X addTotals (&diskInfo [j], &totals);
+X break; /* out of inner for */
+X }
+X }
+X } /* if stat ok */
+X else
+X {
+X fprintf (stderr, "stat: %s ", argv[i]);
+X perror ("");
+X }
+X } /* for each file specified on command line */
+X
+X if ((flags & DI_F_TOTAL) == DI_F_TOTAL && (flags & DI_F_NO_HEADER) != DI_F_NO_HEADER)
+X {
+X printInfo (&totals);
+X }
+X}
+X
+X/*
+X * sortArray ()
+X *
+X * shellsort!
+X *
+X */
+X
+Xstatic void
+X#if defined (CAN_PROTOTYPE)
+XsortArray (char *data, int dataSize, int count, DI_SORT_FUNC compareFunc)
+X#else
+XsortArray (data, dataSize, count, compareFunc)
+X char *data;
+X int dataSize;
+X int count;
+X DI_SORT_FUNC compareFunc;
+X#endif
+X{
+X register int j;
+X char *tempData;
+X int i;
+X int gap;
+X
+X
+X if (count <= 1)
+X {
+X return;
+X }
+X
+X tempData = (char *) malloc ((unsigned) dataSize);
+X if (tempData == (char *) NULL)
+X {
+X fprintf (stderr, "malloc failed in sortArray(). errno %d\n", errno);
+X cleanup ();
+X exit (1);
+X }
+X
+X gap = 1;
+X while (gap < count)
+X {
+X gap = 3 * gap + 1;
+X }
+X
+X for (gap /= 3; gap > 0; gap /= 3)
+X {
+X for (i = gap; i < count; ++i)
+X {
+X memcpy ((char *) tempData, (char *) &(data [i * dataSize]),
+X dataSize);
+X j = i - gap;
+X
+X while (j >= 0 &&
+X compareFunc (&(data [j * dataSize]), tempData) > 0)
+X {
+X memcpy ((char *) &(data [(j + gap) * dataSize]),
+X (char *) &(data [j * dataSize]), dataSize);
+X j -= gap;
+X }
+X
+X j += gap;
+X if (j != i)
+X {
+X memcpy ((char *) &(data [j * dataSize]),
+X (char *) tempData, dataSize);
+X }
+X }
+X }
+X
+X free ((char *) tempData);
+X}
+X
+X
+Xstatic int
+X#if defined (CAN_PROTOTYPE)
+XdiCompare (char *a, char *b)
+X#else
+XdiCompare (a, b)
+X char *a;
+X char *b;
+X#endif
+X{
+X DiskInfo *di1;
+X DiskInfo *di2;
+X
+X
+X di1 = (DiskInfo *) a;
+X di2 = (DiskInfo *) b;
+X
+X
+X switch (sortType)
+X {
+X case DI_SORT_NONE:
+X {
+X break;
+X }
+X
+X case DI_SORT_NAME:
+X {
+X return (strcmp (di1->name, di2->name) * sortOrder);
+X }
+X
+X case DI_SORT_SPECIAL:
+X {
+X return (strcmp (di1->special, di2->special) * sortOrder);
+X }
+X } /* switch on sort type */
+X
+X return 0;
+X}
+X
+X
+X/*
+X * getDiskStatInfo
+X *
+X * gets the disk device number for each entry.
+X *
+X */
+X
+Xstatic void
+X#if defined (CAN_PROTOTYPE)
+XgetDiskStatInfo (void)
+X#else
+XgetDiskStatInfo ()
+X#endif
+X{
+X int i;
+X struct stat statBuf;
+X
+X for (i = 0; i < diCount; ++i)
+X {
+X diskInfo [i].st_dev = (_ulong) DI_UNKNOWN_DEV;
+X
+X if (stat (diskInfo [i].name, &statBuf) == 0)
+X {
+X diskInfo [i].st_dev = (_ulong) statBuf.st_dev;
+X if (debug > 2)
+X {
+X printf ("dev: %s: %ld\n", diskInfo [i].name,
+X diskInfo [i].st_dev);
+X }
+X }
+X else
+X {
+X fprintf (stderr, "stat: %s ", diskInfo [i].name);
+X perror ("");
+X }
+X }
+X}
+X
+X/*
+X * getDiskSpecialInfo
+X *
+X * gets the disk device number for each entry.
+X *
+X */
+X
+Xstatic void
+X#if defined (CAN_PROTOTYPE)
+XgetDiskSpecialInfo (void)
+X#else
+XgetDiskSpecialInfo ()
+X#endif
+X{
+X int i;
+X struct stat statBuf;
+X
+X for (i = 0; i < diCount; ++i)
+X {
+X if (stat (diskInfo [i].special, &statBuf) == 0)
+X {
+X diskInfo [i].sp_dev = (_ulong) statBuf.st_dev;
+X diskInfo [i].sp_rdev = (_ulong) statBuf.st_rdev;
+X if (debug > 2)
+X {
+X printf ("special dev: %s: %ld rdev: %ld\n", diskInfo [i].special,
+X diskInfo [i].sp_dev, diskInfo [i].sp_rdev);
+X }
+X }
+X else
+X {
+X diskInfo [i].sp_dev = 0;
+X diskInfo [i].sp_rdev = 0;
+X }
+X }
+X}
+X
+X/*
+X * checkDiskInfo
+X *
+X * checks the disk information returned for various return values.
+X *
+X */
+X
+Xstatic void
+X#if defined (CAN_PROTOTYPE)
+XcheckDiskInfo (void)
+X#else
+XcheckDiskInfo ()
+X#endif
+X{
+X int i;
+X int j;
+X int dupCount;
+X int len;
+X int maxMountString;
+X int maxSpecialString;
+X int maxTypeString;
+X int maxOptString;
+X int maxMntTimeString;
+X _fs_size_t temp;
+X _ulong sp_dev;
+X _ulong sp_rdev;
+X
+X
+X maxMountString = (flags & DI_F_NO_HEADER) == DI_F_NO_HEADER ? 0 : 5;
+X maxSpecialString = (flags & DI_F_NO_HEADER) == DI_F_NO_HEADER ? 0 : 10;
+X maxTypeString = (flags & DI_F_NO_HEADER) == DI_F_NO_HEADER ? 0 : 7;
+X maxOptString = (flags & DI_F_NO_HEADER) == DI_F_NO_HEADER ? 0 : 7;
+X maxMntTimeString = (flags & DI_F_NO_HEADER) == DI_F_NO_HEADER ? 0 : 26;
+X
+X for (i = 0; i < diCount; ++i)
+X {
+X /* Solaris reports a cdrom as having no free blocks, */
+X /* no available. Their df doesn't always work right! */
+X /* -1 is returned. */
+X if (debug > 2)
+X {
+X printf ("chk: %s free: %f\n", diskInfo [i].name,
+X diskInfo [i].freeBlocks);
+X }
+X if (diskInfo [i].freeBlocks < 0.0)
+X {
+X diskInfo [i].freeBlocks = 0.0;
+X }
+X if (diskInfo [i].availBlocks < 0.0)
+X {
+X diskInfo [i].availBlocks = 0.0;
+X }
+X
+X temp = ~ 0;
+X if (diskInfo [i].totalInodes == temp)
+X {
+X diskInfo [i].totalInodes = 0;
+X diskInfo [i].freeInodes = 0;
+X diskInfo [i].availInodes = 0;
+X }
+X
+X if (debug > 2)
+X {
+X printf ("chk: %s total: %f\n", diskInfo [i].name,
+X diskInfo [i].totalBlocks);
+X }
+X if (diskInfo [i].totalBlocks <= 0.0 &&
+X diskInfo [i].printFlag != DI_BAD)
+X {
+X diskInfo [i].printFlag = DI_IGNORE;
+X if (debug > 2)
+X {
+X printf ("chk: ignore: totalBlocks <= 0: %s\n",
+X diskInfo [i].name);
+X }
+X }
+X
+X checkIgnoreList (&diskInfo [i]);
+X checkIncludeList (&diskInfo [i]);
+X } /* for all disks */
+X
+X /* this loop sets duplicate entries to be ignored. */
+X for (i = 0; i < diCount; ++i)
+X {
+X /* don't need to bother checking real partitions */
+X /* don't bother if already ignored */
+X if (diskInfo [i].sp_rdev != 0 &&
+X (diskInfo [i].printFlag == DI_OK ||
+X ((flags & DI_F_ALL) == DI_F_ALL &&
+X diskInfo [i].printFlag != DI_BAD)))
+X {
+X sp_dev = diskInfo [i].sp_dev;
+X sp_rdev = diskInfo [i].sp_rdev;
+X dupCount = 0;
+X
+X for (j = 0; j < diCount; ++j)
+X {
+X if (diskInfo [j].sp_dev == sp_rdev)
+X {
+X ++dupCount;
+X }
+X }
+X
+X if (debug > 2)
+X {
+X printf ("dup: chk: %s %ld %ld dup: %d\n", diskInfo [i].name,
+X sp_dev, sp_rdev, dupCount);
+X }
+X
+X for (j = 0; dupCount > 0 && j < diCount; ++j)
+X {
+X if (diskInfo [j].sp_rdev == 0 &&
+X diskInfo [j].sp_dev == sp_rdev)
+X {
+X diskInfo [j].printFlag = DI_IGNORE;
+X if (debug > 2)
+X {
+X printf ("chk: ignore: duplicate: %s\n",
+X diskInfo [j].name);
+X }
+X }
+X } /* duplicate check for each disk */
+X } /* if this is a printable disk */
+X else
+X {
+X if (debug > 2)
+X {
+X printf ("chk: dup: not checked: %s prnt: %d dev: %ld rdev: %ld\n",
+X diskInfo [i].name, diskInfo [i].printFlag,
+X diskInfo [i].sp_dev, diskInfo [i].sp_rdev);
+X }
+X }
+X } /* for each disk */
+X
+X /* this loop gets the max string lengths */
+X for (i = 0; i < diCount; ++i)
+X {
+X if (diskInfo [i].printFlag == DI_OK || (flags & DI_F_ALL) == DI_F_ALL)
+X {
+X len = strlen (diskInfo [i].name);
+X if (len > maxMountString)
+X {
+X maxMountString = len;
+X }
+X
+X len = strlen (diskInfo [i].special);
+X if (len > maxSpecialString)
+X {
+X maxSpecialString = len;
+X }
+X
+X len = strlen (diskInfo [i].fsType);
+X if (len > maxTypeString)
+X {
+X maxTypeString = len;
+X }
+X
+X len = strlen (diskInfo [i].options);
+X if (len > maxOptString)
+X {
+X maxOptString = len;
+X }
+X
+X len = strlen (diskInfo [i].mountTime);
+X if (len > maxMntTimeString)
+X {
+X maxMntTimeString = len;
+X }
+X } /* if we are printing this item */
+X } /* for all disks */
+X
+X sprintf (mountFormat, "%%-%d.%ds", maxMountString, maxMountString);
+X sprintf (specialFormat, "%%-%d.%ds", maxSpecialString,
+X maxSpecialString);
+X sprintf (typeFormat, "%%-%d.%ds", maxTypeString, maxTypeString);
+X sprintf (optFormat, "%%-%d.%ds", maxOptString, maxOptString);
+X sprintf (mTimeFormat, "%%-%d.%ds", maxMntTimeString, maxMntTimeString);
+X
+X if (dispBlockSize <= DI_ONE_K)
+X {
+X sprintf (blockFormat, "%%%d.0f", width);
+X }
+X else
+X {
+X sprintf (blockFormat, "%%%d.1f", width);
+X }
+X sprintf (blockLabelFormat, "%%%ds", width);
+X#if defined (HAS_64BIT_STATFS_FLDS)
+X sprintf (inodeFormat, "%%%dllu", inodeWidth);
+X#else
+X sprintf (inodeFormat, "%%%dlu", inodeWidth);
+X#endif
+X sprintf (inodeLabelFormat, "%%%ds", inodeWidth);
+X}
+X
+X/*
+X * usage
+X *
+X */
+X
+Xstatic void
+X#if defined (CAN_PROTOTYPE)
+Xusage (void)
+X#else
+Xusage ()
+X#endif
+X{
+X printf ("di ver $Revision$ Default Format: %s\n", DI_DEFAULT_FORMAT);
+X /* 12345678901234567890123456789012345678901234567890123456789012345678901234567890 */
+X printf ("Usage: di [-ant] [-f format] [-s sort-type] [-i ignore-fstyp-list]\n");
+X printf (" [-I include-fstyp-list] [-w kbyte-width] [-W inode-width] [file [...]]\n");
+X printf (" -a : print all mounted devices; normally, those with 0 total blocks are\n");
+X printf (" not printed. e.g. /dev/proc, /dev/fd.\n");
+X printf (" -d x : size to print blocks in (p - posix (512), k - kbytes,\n");
+X printf (" m - megabytes, g - gigabytes, <x> - numeric size).\n");
+X printf (" -f x : use format string <x>\n");
+X printf (" -i x : ignore file system types in <x>\n");
+X printf (" -I x : include only file system types in <x>\n");
+X printf (" -l : display local filesystems only\n");
+X printf (" -n : don't print header\n");
+X printf (" -s t : sort type; n - no sort, s - by special device, r - reverse\n");
+X printf (" -t : print totals\n");
+X printf (" -w n : use width <n> for kbytes\n");
+X printf (" -W n : use width <n> for i-nodes\n");
+X printf (" Format string values:\n");
+X printf (" m - mount point M - mount point, full length\n");
+X printf (" b - total kbytes B - kbytes available for use\n");
+X printf (" u - used kbytes c - calculated kbytes in use\n");
+X printf (" f - kbytes free v - kbytes available\n");
+X printf (" p - percentage not avail. for use 1 - percentage used\n");
+X printf (" 2 - percentage of user-available space in use.\n");
+X printf (" i - total file slots (i-nodes) U - used file slots\n");
+X printf (" F - free file slots P - percentage file slots used\n");
+X printf (" s - filesystem name S - filesystem name, full length\n");
+X printf (" t - disk partition type T - partition type, full length\n");
+X}
+X
+X
+Xstatic void
+X#if defined (CAN_PROTOTYPE)
+XprocessArgs (int argc, char *argv [])
+X#else
+XprocessArgs (argc, argv)
+X int argc;
+X char *argv [];
+X#endif
+X{
+X int ch;
+X
+X
+X while ((ch = getopt (argc, argv, "Aad:f:hi:I:Flns:tw:W:x:")) != -1)
+X {
+X switch (ch)
+X {
+X case 'A':
+X {
+X formatString = DI_ALL_FORMAT;
+X flags |= DI_F_ALL | DI_F_DEBUG_HDR | DI_F_TOTAL;
+X flags &= ~ DI_F_NO_HEADER;
+X width = 10;
+X inodeWidth = 10;
+X break;
+X }
+X
+X case 'a':
+X {
+X flags |= DI_F_ALL;
+X break;
+X }
+X
+X case 'd':
+X {
+X switch (tolower (*optarg))
+X {
+X case 'p':
+X {
+X dispBlockSize = DI_HALF_K;
+X break;
+X }
+X
+X case 'k':
+X {
+X dispBlockSize = DI_ONE_K;
+X break;
+X }
+X
+X case 'm':
+X {
+X dispBlockSize = DI_ONE_MEG;
+X break;
+X }
+X
+X case 'g':
+X {
+X dispBlockSize = DI_ONE_GIG;
+X break;
+X }
+X
+X default:
+X {
+X if (isdigit ((int) (*optarg)))
+X {
+X dispBlockSize = atof (optarg);
+X }
+X break;
+X }
+X }
+X break;
+X }
+X
+X case 'f':
+X {
+X formatString = optarg;
+X break;
+X }
+X
+X case 'h':
+X {
+X usage ();
+X cleanup ();
+X exit (0);
+X }
+X
+X case 'i':
+X {
+X parseList (&ignoreList, optarg);
+X break;
+X }
+X
+X case 'I':
+X {
+X parseList (&includeList, optarg);
+X break;
+X }
+X
+X case 'l':
+X {
+X flags |= DI_F_LOCAL_ONLY;
+X break;
+X }
+X
+X case 'n':
+X {
+X flags |= DI_F_NO_HEADER;
+X break;
+X }
+X
+X case 's':
+X {
+X switch (ch)
+X {
+X case 's':
+X {
+X sortType = DI_SORT_SPECIAL;
+X break;
+X }
+X
+X case 'n':
+X {
+X sortType = DI_SORT_NONE;
+X break;
+X }
+X
+X case 'r':
+X {
+X sortOrder = DI_SORT_DESCENDING;
+X break;
+X }
+X }
+X break;
+X }
+X
+X case 't':
+X {
+X flags |= DI_F_TOTAL;
+X break;
+X }
+X
+X case 'w':
+X {
+X width = atoi (optarg);
+X break;
+X }
+X
+X case 'W':
+X {
+X inodeWidth = atoi (optarg);
+X break;
+X }
+X
+X case 'x':
+X {
+X debug = atoi (optarg);
+X break;
+X }
+X
+X case '?':
+X {
+X usage ();
+X cleanup ();
+X exit (1);
+X }
+X }
+X }
+X}
+X
+X /* list is assumed to be global */
+Xstatic void
+X#if defined (CAN_PROTOTYPE)
+XparseList (char ***list, char *str)
+X#else
+XparseList (list, str)
+X char ***list;
+X char *str;
+X#endif
+X{
+X char *dstr;
+X char *ptr;
+X char **lptr;
+X int count;
+X int i;
+X int len;
+X
+X i = strlen (str);
+X dstr = (char *) malloc (i + 1);
+X if (dstr == (char *) NULL)
+X {
+X fprintf (stderr, "malloc failed in parseList() (1). errno %d\n", errno);
+X cleanup ();
+X exit (1);
+X }
+X
+X memcpy (dstr, str, i + 1);
+X
+X ptr = strtok (dstr, DI_LIST_SEP);
+X count = 0;
+X while (ptr != (char *) NULL)
+X {
+X ++count;
+X ptr = strtok ((char *) NULL, DI_LIST_SEP);
+X }
+X
+X *list = (char **) malloc ((count + 1) * sizeof (char *));
+X if (*list == (char **) NULL)
+X {
+X fprintf (stderr, "malloc failed in parseList() (2). errno %d\n", errno);
+X cleanup ();
+X exit (1);
+X }
+X
+X ptr = dstr;
+X lptr = *list;
+X for (i = 0; i < count; ++i)
+X {
+X len = strlen (ptr);
+X *lptr = (char *) malloc (len + 1);
+X if (*lptr == (char *) NULL)
+X {
+X fprintf (stderr, "malloc failed in parseList() (3). errno %d\n",
+X errno);
+X cleanup ();
+X exit (1);
+X }
+X strcpy (*lptr, ptr);
+X ptr += len + 1;
+X ++lptr;
+X }
+X
+X *lptr = (char *) NULL;
+X free ((char *) dstr);
+X}
+X
+X
+Xstatic void
+X#if defined (CAN_PROTOTYPE)
+XcheckIgnoreList (DiskInfo *diskInfo)
+X#else
+XcheckIgnoreList (diskInfo)
+X DiskInfo *diskInfo;
+X#endif
+X{
+X char **ptr;
+X
+X /* if the file system type is in the ignore list, skip it */
+X if (ignoreList != (char **) NULL)
+X {
+X ptr = ignoreList;
+X while (*ptr != (char *) NULL)
+X {
+X if (strcmp (*ptr, diskInfo->fsType) == 0)
+X {
+X diskInfo->printFlag = DI_IGNORE;
+X if (debug > 2)
+X {
+X printf ("chkign: ignore: fstype %s match: %s\n", *ptr,
+X diskInfo->name);
+X }
+X break;
+X }
+X ++ptr;
+X }
+X } /* if an ignore list was specified */
+X}
+X
+Xstatic void
+X#if defined (CAN_PROTOTYPE)
+XcheckIncludeList (DiskInfo *diskInfo)
+X#else
+XcheckIncludeList (diskInfo)
+X DiskInfo *diskInfo;
+X#endif
+X{
+X char **ptr;
+X
+X /* if the file system type is not in the include list, skip it */
+X if (includeList != (char **) NULL)
+X {
+X ptr = includeList;
+X while (*ptr != (char *) NULL)
+X {
+X if (strcmp (*ptr, diskInfo->fsType) == 0)
+X {
+X diskInfo->printFlag = DI_OK;
+X break;
+X }
+X else
+X {
+X diskInfo->printFlag = DI_IGNORE;
+X if (debug > 2)
+X {
+X printf ("chkinc: ! include: fstype %s match: %s\n", *ptr,
+X diskInfo->name);
+X }
+X }
+X ++ptr;
+X }
+X } /* if an include list was specified */
+X}
+X
+X
+X#if defined (HAS_FS_INFO)
+X
+X/*
+X * getDiskEntries
+X *
+X * For BeOS.
+X *
+X */
+X
+Xstatic int
+XgetDiskEntries (void)
+X{
+X status_t stat;
+X int idx;
+X int32 count;
+X dev_t dev;
+X char buff [B_FILE_NAME_LENGTH];
+X fs_info fsinfo;
+X double mult;
+X node_ref nref;
+X BDirectory *dir;
+X BEntry entry;
+X BPath path;
+X
+X count = 0;
+X while ((dev = next_dev (&count)) != B_BAD_VALUE)
+X {
+X if ((stat = fs_stat_dev (dev, &fsinfo)) == B_BAD_VALUE)
+X {
+X break;
+X }
+X
+X idx = diCount;
+X ++diCount;
+X diskInfo = (DiskInfo *) Realloc ((char *) diskInfo,
+X sizeof (DiskInfo) * diCount);
+X memset ((char *) &diskInfo [idx], '\0', sizeof (DiskInfo));
+X diskInfo [idx].printFlag = DI_OK;
+X *buff = '\0';
+X nref.device = dev;
+X nref.node = fsinfo.root;
+X dir = new BDirectory (&nref);
+X stat = dir->GetEntry (&entry);
+X stat = entry.GetPath (&path);
+X strncpy (diskInfo [idx].name, path.Path (), DI_NAME_LEN);
+X strncpy (diskInfo [idx].special, fsinfo.device_name, DI_SPEC_NAME_LEN);
+X strncpy (diskInfo [idx].fsType, fsinfo.fsh_name, DI_TYPE_LEN);
+X diskInfo [idx].isLocal = TRUE;
+X mult = (double) (long) fsinfo.block_size / dispBlockSize;
+X diskInfo [idx].totalBlocks =
+X ((double) (_s_fs_size_t) fsinfo.total_blocks * mult);
+X diskInfo [idx].freeBlocks =
+X ((double) (_s_fs_size_t) fsinfo.free_blocks * mult);
+X diskInfo [idx].availBlocks =
+X ((double) (_s_fs_size_t) fsinfo.free_blocks * mult);
+X diskInfo [idx].totalInodes = fsinfo.total_nodes;
+X diskInfo [idx].freeInodes = fsinfo.free_nodes;
+X diskInfo [idx].availInodes = fsinfo.free_nodes;
+X
+X checkIgnoreList (&diskInfo [idx]);
+X checkIncludeList (&diskInfo [idx]);
+X
+X if (debug > 0)
+X {
+X printf ("mnt:%s - %s\n", diskInfo [idx].name,
+X diskInfo [idx].special);
+X printf ("dev:%d fs:%s\n", dev, diskInfo [idx].fsType);
+X }
+X if (debug > 1)
+X {
+X printf ("%s: %s\n", diskInfo [idx].name, diskInfo [idx].fsType);
+X printf ("\tmult:%f\n", mult);
+X printf ("\tblocks: tot:%ld free:%ld\n",
+X fsinfo.total_blocks, fsinfo.free_blocks);
+X printf ("\tinodes: tot:%ld free:%ld\n",
+X fsinfo.total_nodes, fsinfo.free_nodes);
+X }
+X }
+X return 0;
+X}
+X
+Xstatic void
+XgetDiskInfo (void)
+X{
+X return;
+X}
+X
+X#endif
+X
+X#if defined (HAS_GETMNTENT) && ! defined (HAS_SETMNTENT)
+X
+X# define DFS_FS_TABLE "/etc/dfs/fstypes"
+X
+X/*
+X * getDiskEntries
+X *
+X * For SysV.4, we open the file and call getmntent () repeatedly.
+X *
+X */
+X
+Xstatic int
+XgetDiskEntries ()
+X{
+X FILE *f;
+X int idx;
+X int i;
+X struct mnttab mntEntry;
+X char buff [80];
+X time_t mtime;
+X char *devp; /* local ptr to dev entry */
+X
+X
+X if ((flags & DI_F_LOCAL_ONLY) == DI_F_LOCAL_ONLY)
+X {
+X i = remoteFileSystemCount;
+X
+X if ((f = fopen (DFS_FS_TABLE, "r")) != (FILE *) NULL)
+X {
+X fgets (buff, 80, f);
+X if (debug > 1)
+X {
+X printf ("remote file system type: %s\n", buff);
+X }
+X sscanf (buff, "%s", remoteFileSystemTypes [i++]);
+X fclose (f);
+X }
+X
+X remoteFileSystemCount = i;
+X }
+X
+X if ((f = fopen (DI_MOUNT_FILE, "r")) == (FILE *) NULL)
+X {
+X fprintf (stderr, "Unable to open: %s errno %d\n", DI_MOUNT_FILE, errno);
+X return -1;
+X }
+X
+X while (getmntent (f, &mntEntry) == 0)
+X {
+X idx = diCount;
+X ++diCount;
+X diskInfo = (DiskInfo *) Realloc ((char *) diskInfo,
+X sizeof (DiskInfo) * diCount);
+X memset ((char *) &diskInfo [idx], '\0', sizeof (DiskInfo));
+X diskInfo [idx].printFlag = DI_OK;
+X
+X strncpy (diskInfo [idx].special, mntEntry.mnt_special,
+X DI_SPEC_NAME_LEN);
+X strncpy (diskInfo [idx].name, mntEntry.mnt_mountp, DI_NAME_LEN);
+X# if defined (MNTOPT_IGNORE)
+X if (strstr (mntEntry.mnt_mntopts, MNTOPT_IGNORE) != (char *) NULL)
+X# else
+X if (strstr (mntEntry.mnt_mntopts, "ignore") != (char *) NULL)
+X# endif
+X {
+X diskInfo [idx].printFlag = DI_IGNORE;
+X if (debug > 2)
+X {
+X printf ("mnt: ignore: mntopt 'ignore': %s\n",
+X diskInfo [idx].name);
+X }
+X }
+X# if defined (MNTOPT_DEV)
+X sprintf (buff, "%s=", MNTOPT_DEV);
+X if ((devp = strstr (mntEntry.mnt_mntopts, buff)) != (char *) NULL)
+X# else
+X if ((devp = strstr (mntEntry.mnt_mntopts, "dev=")) != (char *) NULL)
+X# endif
+X {
+X if (devp != mntEntry.mnt_mntopts)
+X {
+X --devp;
+X }
+X *devp = 0; /* point to preceeding comma and cut off */
+X }
+X strncpy (diskInfo [idx].options, mntEntry.mnt_mntopts, DI_OPT_LEN);
+X mtime = atol (mntEntry.mnt_time);
+X strncpy (diskInfo [idx].mountTime, ctime (&mtime), DI_MNT_TIME_LEN);
+X
+X /* get the file system type now... */
+X strncpy (diskInfo [idx].fsType, mntEntry.mnt_fstype, DI_TYPE_LEN);
+X
+X diskInfo [idx].isLocal = TRUE;
+X for (i = 0; i < remoteFileSystemCount; ++i)
+X {
+X if (strcmp (diskInfo [idx].fsType, remoteFileSystemTypes [i]) == 0)
+X {
+X diskInfo [idx].isLocal = FALSE;
+X }
+X }
+X
+X checkIgnoreList (&diskInfo [idx]);
+X checkIncludeList (&diskInfo [idx]);
+X
+X if (debug > 0)
+X {
+X printf ("mnt:%s - %s\n", diskInfo [idx].name,
+X diskInfo [idx].special);
+X }
+X }
+X
+X fclose (f);
+X return 0;
+X}
+X
+X#endif /* HAS_GETMNTENT */
+X
+X#if ! defined (HAS_GETMNTENT) && ! defined (HAS_MNTCTL) && \
+X ! defined (HAS_GETMNTINFO) && ! defined (HAS_GETMNT) && \
+X ! defined (HAS_GETDISKFREESPACE) && ! defined (HAS_FS_INFO)
+X
+X/*
+X * getDiskEntries
+X *
+X * For SysV.3 we open the file and read it ourselves.
+X *
+X */
+X
+Xstatic int
+XgetDiskEntries ()
+X{
+X FILE *f;
+X int idx;
+X struct mnttab mntEntry;
+X
+X
+X if ((f = fopen (DI_MOUNT_FILE, "r")) == (FILE *) NULL)
+X {
+X fprintf (stderr, "Unable to open: %s errno %d\n", DI_MOUNT_FILE, errno);
+X return -1;
+X }
+X
+X while (fread ((char *) &mntEntry, sizeof (struct mnttab), 1, f) == 1)
+X {
+X /* xenix allows null mount table entries */
+X /* sco nfs background mounts are marked as "nothing" */
+X if (mntEntry.mt_filsys [0] &&
+X strcmp (mntEntry.mt_filsys, "nothing") != 0)
+X {
+X idx = diCount;
+X ++diCount;
+X diskInfo = (DiskInfo *) Realloc ((char *) diskInfo,
+X sizeof (DiskInfo) * diCount);
+X memset ((char *) &diskInfo [idx], '\0', sizeof (DiskInfo));
+X diskInfo [idx].printFlag = DI_OK;
+X diskInfo [idx].isLocal = TRUE;
+X
+X# if defined (COHERENT)
+X /* Coherent seems to have these fields reversed. oh well. */
+X strncpy (diskInfo [idx].name, mntEntry.mt_dev, DI_NAME_LEN);
+X strncpy (diskInfo [idx].special, mntEntry.mt_filsys, DI_SPEC_NAME_LEN);
+X# else
+X strncpy (diskInfo [idx].special, mntEntry.mt_dev, DI_SPEC_NAME_LEN);
+X strncpy (diskInfo [idx].name, mntEntry.mt_filsys, DI_NAME_LEN);
+X# endif
+X strncpy (diskInfo [idx].options, mntEntry.mnt_mntopts, DI_OPT_LEN);
+X strncpy (diskInfo [idx].mountTime, mntEntry.mnt_time,
+X DI_MNT_TIME_LEN);
+X }
+X
+X if (debug > 0)
+X {
+X printf ("mnt:%s - %s\n", diskInfo [idx].name,
+X diskInfo [idx].special);
+X }
+X }
+X
+X fclose (f);
+X return 0;
+X}
+X
+X#endif /* Sys V.3 */
+X
+X#if defined (HAS_GETMNTENT) && defined (HAS_SETMNTENT) && \
+X defined (HAS_ENDMNTENT)
+X
+X/*
+X * getDiskEntries
+X *
+X * SunOS supplies an open and close routine for the mount table.
+X *
+X */
+X
+Xstatic int
+XgetDiskEntries ()
+X{
+X FILE *f;
+X int idx;
+X struct mntent *mntEntry;
+X char *devp; /* local ptr to dev entry */
+X
+X
+X#if defined (HAS_SETMNTENT_ONE_ARG)
+X if ((f = setmntent (DI_MOUNT_FILE)) == (FILE *) NULL)
+X#else
+X if ((f = setmntent (DI_MOUNT_FILE, "r")) == (FILE *) NULL)
+X#endif
+X {
+X fprintf (stderr, "Unable to open: %s errno %d\n", DI_MOUNT_FILE, errno);
+X return -1;
+X }
+X
+X while ((mntEntry = getmntent (f)) != (struct mntent *) NULL)
+X {
+X idx = diCount;
+X ++diCount;
+X diskInfo = (DiskInfo *) Realloc ((char *) diskInfo,
+X sizeof (DiskInfo) * diCount);
+X memset ((char *) &diskInfo [idx], '\0', sizeof (DiskInfo));
+X diskInfo [idx].printFlag = DI_OK;
+X diskInfo [idx].isLocal = TRUE;
+X
+X strncpy (diskInfo [idx].special, mntEntry->mnt_fsname, DI_SPEC_NAME_LEN);
+X strncpy (diskInfo [idx].name, mntEntry->mnt_dir, DI_NAME_LEN);
+X strncpy (diskInfo [idx].fsType, mntEntry->mnt_type, DI_TYPE_LEN);
+X
+X if (strcmp (mntEntry->mnt_type, MNTTYPE_IGNORE) == 0)
+X {
+X diskInfo [idx].printFlag = DI_IGNORE;
+X if (debug > 2)
+X {
+X printf ("mnt: ignore: mntopt 'ignore': %s\n",
+X diskInfo [idx].name);
+X }
+X }
+X
+X if ((devp = strstr (mntEntry->mnt_opts, "dev=")) != (char *) NULL)
+X {
+X if (devp != mntEntry->mnt_opts)
+X {
+X --devp;
+X }
+X *devp = 0; /* point to preceeding comma and cut off */
+X }
+X strncpy (diskInfo [idx].options, mntEntry->mnt_opts, DI_OPT_LEN);
+X
+X checkIgnoreList (&diskInfo [idx]);
+X checkIncludeList (&diskInfo [idx]);
+X
+X if (debug > 0)
+X {
+X printf ("mnt:%s - %s : %s\n", diskInfo [idx].name,
+X diskInfo [idx].special, diskInfo [idx].fsType);
+X }
+X }
+X
+X endmntent (f);
+X return 0;
+X}
+X
+X#endif /* HAS_GETMNTENT && HAS_SETMNTENT && HAS_ENDMNTENT */
+X
+X#if defined (HAS_GETMNTINFO)
+X
+X/*
+X * getDiskEntries
+X *
+X * OSF/1 does this with a system call and library routine
+X *
+X * [mogul@wrl.dec.com (Jeffrey Mogul)]
+X */
+X
+X#if defined (INITMOUNTNAMES)
+Xstatic char *mnt_names [] = INITMOUNTNAMES;
+X# define MNT_NUMTYPES (MOUNT_MAXTYPE + 1)
+X#endif
+X
+X /* osf/1 mount flags start w/M_ vs. MNT_ */
+X /* this saves us from lots of duplicate code */
+X#if defined (M_RDONLY)
+X# define MNT_RDONLY M_RDONLY
+X#endif
+X#if defined (M_SYNCHRONOUS)
+X# define MNT_SYNCHRONOUS M_SYNCHRONOUS
+X#endif
+X#if defined (M_NOEXEC)
+X# define MNT_NOEXEC M_NOEXEC
+X#endif
+X#if defined (M_NOSUID)
+X# define MNT_NOSUID M_NOSUID
+X#endif
+X#if defined (M_NODEV)
+X# define MNT_NODEV M_NODEV
+X#endif
+X#if defined (M_GRPID)
+X# define MNT_GRPID M_GRPID
+X#endif
+X#if defined (M_EXPORTED)
+X# define MNT_EXPORTED M_EXPORTED
+X#endif
+X#if defined (M_EXRDONLY)
+X# define MNT_EXRDONLY M_EXRDONLY
+X#endif
+X#if defined (M_EXRDMOSTLY)
+X# define MNT_EXRDMOSTLY M_EXRDMOSTLY
+X#endif
+X#if defined (M_SECURE)
+X# define MNT_SECURE M_SECURE
+X#endif
+X#if defined (M_LOCAL)
+X# define MNT_LOCAL M_LOCAL
+X#endif
+X#if defined (M_QUOTA)
+X# define MNT_QUOTA M_QUOTA
+X#endif
+X
+Xstatic int
+XgetDiskEntries ()
+X{
+X int count;
+X int idx;
+X int len;
+X short fstype;
+X struct statfs *mntbufp;
+X double mult;
+X
+X count = getmntinfo (&mntbufp, MNT_WAIT);
+X if (count < 1)
+X {
+X fprintf (stderr, "Unable to do getmntinfo () errno %d\n", errno);
+X return -1;
+X }
+X
+X diCount = count;
+X diskInfo = (DiskInfo *) malloc (sizeof (DiskInfo) * count);
+X if (diskInfo == (DiskInfo *) NULL)
+X {
+X fprintf (stderr, "malloc failed for diskInfo. errno %d\n", errno);
+X return -1;
+X }
+X memset ((char *) diskInfo, '\0', sizeof (DiskInfo) * count);
+X
+X if (debug > 1)
+X {
+X printf ("type_len %d name_len %d spec_name_len %d\n", DI_TYPE_LEN,
+X DI_NAME_LEN, DI_SPEC_NAME_LEN);
+X }
+X
+X for (idx = 0; idx < count; idx++)
+X {
+X diskInfo [idx].printFlag = DI_OK;
+X diskInfo [idx].isLocal = FALSE;
+X#if defined (MNT_LOCAL)
+X if ((mntbufp [idx].f_flags & MNT_LOCAL) == MNT_LOCAL)
+X {
+X diskInfo [idx].isLocal = TRUE;
+X }
+X#endif
+X
+X if (diskInfo [idx].isLocal == FALSE &&
+X (flags & DI_F_LOCAL_ONLY) == DI_F_LOCAL_ONLY)
+X {
+X diskInfo [idx].printFlag = DI_IGNORE;
+X if (debug > 2)
+X {
+X printf ("mnt: ignore: remote: %s\n",
+X diskInfo [idx].name);
+X }
+X }
+X
+X strncpy (diskInfo [idx].special, mntbufp [idx].f_mntfromname,
+X DI_SPEC_NAME_LEN);
+X strncpy (diskInfo [idx].name, mntbufp [idx].f_mntonname, DI_NAME_LEN);
+X
+X mult = 1.0;
+X
+X# if defined (HAS_GETMNTINFO_FSIZE) /* 1.x */
+X mult = (double) mntbufp [idx].f_fsize / dispBlockSize;
+X# endif
+X# if defined (HAS_GETMNTINFO_BSIZE) /* 2.x */
+X mult = (double) mntbufp [idx].f_bsize / dispBlockSize;
+X# endif
+X diskInfo [idx].totalBlocks = ((double) (_s_fs_size_t) mntbufp [idx].f_blocks * mult);
+X diskInfo [idx].freeBlocks = ((double) (_s_fs_size_t) mntbufp [idx].f_bfree * mult);
+X diskInfo [idx].availBlocks = ((double) (_s_fs_size_t) mntbufp [idx].f_bavail * mult);
+X
+X diskInfo [idx].totalInodes = mntbufp [idx].f_files;
+X diskInfo [idx].freeInodes = mntbufp [idx].f_ffree;
+X diskInfo [idx].availInodes = mntbufp [idx].f_ffree;
+X
+X fstype = mntbufp [idx].f_type;
+X# if ! defined (I_SYS_FSTYP) && ! defined (INITMOUNTNAMES) && \
+X ! defined (HAS_GETMNTINFO_FSTYPENAME)
+X if ((fstype >= 0) && (fstype <= MOUNT_MAXTYPE))
+X {
+X switch (fstype)
+X {
+X# if defined (MOUNT_NONE)
+X case MOUNT_NONE: /* No Filesystem */
+X {
+X strncpy (diskInfo [idx].fsType, "none", DI_TYPE_LEN);
+X break;
+X }
+X# endif
+X
+X# if defined (MOUNT_UFS)
+X case MOUNT_UFS: /* UNIX "Fast" Filesystem */
+X {
+X strncpy (diskInfo [idx].fsType, "ufs", DI_TYPE_LEN);
+X break;
+X }
+X# endif
+X
+X# if defined (MOUNT_NFS)
+X case MOUNT_NFS: /* Network Filesystem */
+X {
+X strncpy (diskInfo [idx].fsType, "nfs", DI_TYPE_LEN);
+X break;
+X }
+X# endif
+X
+X# if defined (MOUNT_MFS)
+X case MOUNT_MFS: /* Memory Filesystem */
+X {
+X strncpy (diskInfo [idx].fsType, "mfs", DI_TYPE_LEN);
+X break;
+X }
+X# endif
+X
+X# if defined (MOUNT_MSDOS)
+X case MOUNT_MSDOS: /* MSDOS Filesystem */
+X {
+X strncpy (diskInfo [idx].fsType, "msdos", DI_TYPE_LEN);
+X break;
+X }
+X# endif
+X
+X# if defined (MOUNT_LFS)
+X case MOUNT_LFS:
+X {
+X strncpy (diskInfo [idx].fsType, "lfs", DI_TYPE_LEN);
+X break;
+X }
+X# endif
+X
+X# if defined (MOUNT_LOFS)
+X case MOUNT_LOFS:
+X {
+X strncpy (diskInfo [idx].fsType, "lofs", DI_TYPE_LEN);
+X break;
+X }
+X# endif
+X
+X# if defined (MOUNT_FDESC)
+X case MOUNT_FDESC:
+X {
+X strncpy (diskInfo [idx].fsType, "fdesc", DI_TYPE_LEN);
+X break;
+X }
+X# endif
+X
+X# if defined (MOUNT_PORTAL)
+X case MOUNT_PORTAL:
+X {
+X strncpy (diskInfo [idx].fsType, "portal", DI_TYPE_LEN);
+X break;
+X }
+X# endif
+X
+X# if defined (MOUNT_NULL)
+X case MOUNT_NULL:
+X {
+X strncpy (diskInfo [idx].fsType, "null", DI_TYPE_LEN);
+X break;
+X }
+X# endif
+X
+X# if defined (MOUNT_UMAP)
+X case MOUNT_UMAP:
+X {
+X strncpy (diskInfo [idx].fsType, "umap", DI_TYPE_LEN);
+X break;
+X }
+X# endif
+X
+X# if defined (MOUNT_KERNFS)
+X case MOUNT_KERNFS:
+X {
+X strncpy (diskInfo [idx].fsType, "kernfs", DI_TYPE_LEN);
+X break;
+X }
+X# endif
+X
+X# if defined (MOUNT_PROCFS)
+X case MOUNT_PROCFS: /* proc filesystem */
+X {
+X strncpy (diskInfo [idx].fsType, "pfs", DI_TYPE_LEN);
+X break;
+X }
+X# endif
+X
+X# if defined (MOUNT_AFS)
+X case MOUNT_AFS:
+X {
+X strncpy (diskInfo [idx].fsType, "afs", DI_TYPE_LEN);
+X break;
+X }
+X# endif
+X
+X# if defined (MOUNT_ISOFS)
+X case MOUNT_ISOFS: /* iso9660 cdrom */
+X {
+X strncpy (diskInfo [idx].fsType, "iso9660fs", DI_TYPE_LEN);
+X break;
+X }
+X# endif
+X
+X# if defined (MOUNT_ISO9660) && ! defined (MOUNT_CD9660)
+X case MOUNT_ISO9660: /* iso9660 cdrom */
+X {
+X strncpy (diskInfo [idx].fsType, "iso9660", DI_TYPE_LEN);
+X break;
+X }
+X# endif
+X
+X# if defined (MOUNT_CD9660)
+X case MOUNT_CD9660: /* iso9660 cdrom */
+X {
+X strncpy (diskInfo [idx].fsType, "cd9660", DI_TYPE_LEN);
+X break;
+X }
+X# endif
+X
+X# if defined (MOUNT_UNION)
+X case MOUNT_UNION:
+X {
+X strncpy (diskInfo [idx].fsType, "union", DI_TYPE_LEN);
+X break;
+X }
+X# endif
+X } /* switch on mount type */
+X }
+X# else
+X# if defined (HAS_GETMNTINFO_FSTYPENAME)
+X strncpy (diskInfo [idx].fsType, mntbufp [idx].f_fstypename, DI_TYPE_LEN);
+X# else
+X /* could use getvfsbytype here... */
+X if ((fstype >= 0) && (fstype < MNT_NUMTYPES))
+X {
+X strncpy (diskInfo [idx].fsType, mnt_names [fstype], DI_TYPE_LEN);
+X }
+X else
+X {
+X sprintf (diskInfo [idx].fsType, DI_UNKNOWN_FSTYPE, fstype);
+X }
+X# endif
+X# endif /* has fs_types.h */
+X
+X#if defined (MNT_RDONLY)
+X if ((mntbufp [idx].f_flags & MNT_RDONLY) == MNT_RDONLY)
+X {
+X strcat (diskInfo [idx].options, "ro,");
+X }
+X else
+X {
+X strcat (diskInfo [idx].options, "rw,");
+X }
+X#endif
+X#if defined (MNT_SYNCHRONOUS)
+X if ((mntbufp [idx].f_flags & MNT_SYNCHRONOUS) == MNT_SYNCHRONOUS)
+X {
+X strcat (diskInfo [idx].options, "sync,");
+X }
+X#endif
+X#if defined (MNT_NOEXEC)
+X if ((mntbufp [idx].f_flags & MNT_NOEXEC) == MNT_NOEXEC)
+X {
+X strcat (diskInfo [idx].options, "noexec,");
+X }
+X#endif
+X#if defined (MNT_NOSUID)
+X if ((mntbufp [idx].f_flags & MNT_NOSUID) != MNT_NOSUID)
+X {
+X strcat (diskInfo [idx].options, "suid,");
+X }
+X#endif
+X#if defined (MNT_NODEV)
+X if ((mntbufp [idx].f_flags & MNT_NODEV) == MNT_NODEV)
+X {
+X strcat (diskInfo [idx].options, "nodev,");
+X }
+X#endif
+X#if defined (MNT_GRPID)
+X if ((mntbufp [idx].f_flags & MNT_GRPID) == MNT_GRPID)
+X {
+X strcat (diskInfo [idx].options, "grpid,");
+X }
+X#endif
+X#if defined (MNT_UNION)
+X if ((mntbufp [idx].f_flags & MNT_UNION) == MNT_UNION)
+X {
+X strcat (diskInfo [idx].options, "union,");
+X }
+X#endif
+X#if defined (MNT_ASYNC)
+X if ((mntbufp [idx].f_flags & MNT_ASYNC) == MNT_ASYNC)
+X {
+X strcat (diskInfo [idx].options, "async,");
+X }
+X#endif
+X#if defined (MNT_EXRDONLY)
+X if ((mntbufp [idx].f_flags & MNT_EXRDONLY) == MNT_EXRDONLY)
+X {
+X strcat (diskInfo [idx].options, "exported ro,");
+X }
+X#endif
+X#if defined (MNT_EXPORTED)
+X if ((mntbufp [idx].f_flags & MNT_EXPORTED) == MNT_EXPORTED)
+X {
+X strcat (diskInfo [idx].options, "exported,");
+X }
+X#endif
+X#if defined (MNT_EXRDMOSTLY)
+X if ((mntbufp [idx].f_flags & MNT_EXRDMOSTLY) == MNT_EXRDMOSTLY)
+X {
+X /* what's read-mostly ? */
+X strcat (diskInfo [idx].options, "exported read-mostly,");
+X }
+X#endif
+X#if defined (MNT_DEFEXPORTED)
+X if ((mntbufp [idx].f_flags & MNT_DEFEXPORTED) == MNT_DEFEXPORTED)
+X {
+X /* what's this ? */
+X strcat (diskInfo [idx].options, "exported world,");
+X }
+X#endif
+X#if defined (MNT_EXPORTANON)
+X if ((mntbufp [idx].f_flags & MNT_EXPORTANON) == MNT_EXPORTANON)
+X {
+X strcat (diskInfo [idx].options, "exported anon,");
+X }
+X#endif
+X#if defined (MNT_EXKERB)
+X if ((mntbufp [idx].f_flags & MNT_EXKERB) == MNT_EXKERB)
+X {
+X strcat (diskInfo [idx].options, "exported kerberos,");
+X }
+X#endif
+X#if defined (MNT_LOCAL)
+X if ((mntbufp [idx].f_flags & MNT_LOCAL) == MNT_LOCAL)
+X {
+X strcat (diskInfo [idx].options, "local,");
+X }
+X#endif
+X#if defined (MNT_QUOTA)
+X if ((mntbufp [idx].f_flags & MNT_QUOTA) == MNT_QUOTA)
+X {
+X strcat (diskInfo [idx].options, "quota,");
+X }
+X#endif
+X#if defined (MNT_ROOTFS)
+X if ((mntbufp [idx].f_flags & MNT_ROOTFS) == MNT_ROOTFS)
+X {
+X strcat (diskInfo [idx].options, "root,");
+X }
+X#endif
+X#if defined (MNT_USER)
+X if ((mntbufp [idx].f_flags & MNT_USER) == MNT_USER)
+X {
+X strcat (diskInfo [idx].options, "user,");
+X }
+X#endif
+X#if defined (MNT_SECURE)
+X if ((mntbufp [idx].f_flags & MNT_SECURE) == MNT_SECURE)
+X {
+X strcat (diskInfo [idx].options, "secure,");
+X }
+X#endif
+X
+X len = strlen (diskInfo [idx].options);
+X if (len > 0)
+X {
+X --len;
+X }
+X if (diskInfo [idx].options [len]==',')
+X {
+X diskInfo [idx].options [len] = '\0';
+X }
+X
+X if (debug > 1)
+X {
+X printf ("%s: %s\n", diskInfo [idx].name, diskInfo [idx].fsType);
+X printf ("\tblocks: tot:%ld free:%ld avail:%ld\n",
+X mntbufp [idx].f_blocks, mntbufp [idx].f_bfree,
+X mntbufp [idx].f_bavail);
+X printf ("\tmult: %f\n", mult);
+X# if defined (HAS_GETMNTINFO_FSIZE)
+X printf ("\tfsize:%ld \n", mntbufp [idx].f_fsize);
+X printf ("\tbsize:%ld \n", mntbufp [idx].f_bsize);
+X# endif
+X# if defined (HAS_GETMNTINFO_BSIZE)
+X printf ("\tbsize:%ld \n", mntbufp [idx].f_bsize);
+X printf ("\tiosize:%ld \n", mntbufp [idx].f_iosize);
+X# endif
+X printf ("\tinodes: tot:%ld free:%ld\n",
+X mntbufp [idx].f_files, mntbufp [idx].f_ffree);
+X }
+X }
+X
+X free ((char *) mntbufp); /* man page says this can't be freed. */
+X /* is it ok to try? */
+X return 0;
+X}
+X
+X/* this is a no-op; we have already done all the work */
+Xstatic void
+XgetDiskInfo ()
+X{
+X}
+X
+X#endif /* HAS_GETMNTINFO */
+X
+X#if defined (HAS_GETMNT)
+X
+X/*
+X * getDiskEntries
+X *
+X * ULTRIX does this with a system call. The system call allows one
+X * to retrieve the information in a series of calls, but coding that
+X * looks a little tricky; I just allocate a huge buffer and do it in
+X * one shot.
+X *
+X * [mogul@wrl.dec.com (Jeffrey Mogul)]
+X */
+X
+Xstatic int
+XgetDiskEntries ()
+X{
+X int count;
+X int bufsize;
+X int idx;
+X short fstype;
+X struct fs_data *fsdbuf;
+X int start;
+X int len;
+X
+X
+X bufsize = NMOUNT * sizeof (struct fs_data); /* enough for max # mounts */
+X fsdbuf = (struct fs_data *) malloc (bufsize);
+X if (fsdbuf == (struct fs_data *) NULL)
+X {
+X fprintf (stderr, "malloc (%d) for getmnt () failed errno %d\n",
+X bufsize, errno);
+X return -1;
+X }
+X
+X start = 0;
+X count = getmnt (&start, fsdbuf, bufsize, STAT_MANY, 0);
+X if (count < 1)
+X {
+X fprintf (stderr, "Unable to do getmnt () [= %d] errno %d\n",
+X count, errno);
+X free ((char *) fsdbuf);
+X return -1;
+X }
+X
+X diCount = count;
+X diskInfo = (DiskInfo *) malloc (sizeof (DiskInfo) * count);
+X if (diskInfo == (DiskInfo *) NULL)
+X {
+X fprintf (stderr, "malloc failed for diskInfo. errno %d\n", errno);
+X free ((char *) fsdbuf);
+X return -1;
+X }
+X memset ((char *) diskInfo, '\0', sizeof (DiskInfo) * count);
+X
+X for (idx = 0; idx < count; idx++)
+X {
+X diskInfo [idx].printFlag = DI_OK;
+X diskInfo [idx].isLocal = TRUE;
+X
+X if ((fsdbuf [idx].fd_req.flags & M_LOCAL) != M_LOCAL)
+X {
+X diskInfo [idx].isLocal = FALSE;
+X }
+X
+X if (diskInfo [idx].isLocal == FALSE &&
+X (flags & DI_F_LOCAL_ONLY) == DI_F_LOCAL_ONLY)
+X {
+X diskInfo [idx].printFlag = DI_IGNORE;
+X if (debug > 2)
+X {
+X printf ("mnt: ignore: remote: %s\n",
+X diskInfo [idx].name);
+X }
+X }
+X
+X strncpy (diskInfo [idx].special, fsdbuf [idx].fd_devname, DI_SPEC_NAME_LEN);
+X strncpy (diskInfo [idx].name, fsdbuf [idx].fd_path, DI_NAME_LEN);
+X
+X /* ULTRIX keeps these fields in units of 1K byte */
+X diskInfo [idx].totalBlocks = fsdbuf [idx].fd_btot;
+X diskInfo [idx].freeBlocks = fsdbuf [idx].fd_bfree;
+X diskInfo [idx].availBlocks = (int) fsdbuf [idx].fd_bfreen;
+X
+X diskInfo [idx].totalInodes = fsdbuf [idx].fd_gtot;
+X diskInfo [idx].freeInodes = fsdbuf [idx].fd_gfree;
+X diskInfo [idx].availInodes = fsdbuf [idx].fd_gfree;
+X
+X fstype = fsdbuf [idx].fd_fstype;
+X if (fstype == GT_UNKWN)
+X {
+X diskInfo [idx].printFlag = DI_IGNORE;
+X if (debug > 2)
+X {
+X printf ("mnt: ignore: disk type unknown: %s\n",
+X diskInfo [idx].name);
+X }
+X }
+X else if ((fstype > 0) && (fstype < GT_NUMTYPES))
+X {
+X strncpy (diskInfo [idx].fsType, gt_names [fstype], DI_TYPE_LEN);
+X }
+X else
+X {
+X sprintf (diskInfo [idx].fsType, "Unknown fstyp %.2d", fstype);
+X }
+X
+X if ((fsdbuf [idx].fd_req.flags & M_RONLY) == M_RONLY)
+X {
+X strcat (diskInfo [idx].options, "ro,");
+X }
+X else
+X {
+X strcat (diskInfo [idx].options, "rw,");
+X }
+X if ((fsdbuf [idx].fd_req.flags & M_NOSUID) != M_NOSUID)
+X {
+X strcat (diskInfo [idx].options, "suid,");
+X }
+X if ((fsdbuf [idx].fd_req.flags & M_QUOTA) == M_QUOTA)
+X {
+X strcat (diskInfo [idx].options, "quota,");
+X }
+X if ((fsdbuf [idx].fd_req.flags & M_LOCAL) != M_LOCAL)
+X {
+X strcat (diskInfo [idx].options, "remote,");
+X }
+X if ((fsdbuf [idx].fd_req.flags & M_NODEV) == M_NODEV)
+X {
+X strcat (diskInfo [idx].options, "nodev,");
+X }
+X if ((fsdbuf [idx].fd_req.flags & M_FORCE) == M_FORCE)
+X {
+X strcat (diskInfo [idx].options, "force,");
+X }
+X if ((fsdbuf [idx].fd_req.flags & M_SYNC) == M_SYNC)
+X {
+X strcat (diskInfo [idx].options, "sync,");
+X }
+X if ((fsdbuf [idx].fd_req.flags & M_NOCACHE) == M_NOCACHE)
+X {
+X strcat (diskInfo [idx].options, "nocache,");
+X }
+X if ((fsdbuf [idx].fd_req.flags & M_EXPORTED) == M_EXPORTED)
+X {
+X strcat (diskInfo [idx].options, "exported," );
+X }
+X if ((fsdbuf [idx].fd_req.flags & M_EXRONLY) == M_EXRONLY)
+X {
+X strcat (diskInfo [idx].options, "exported ro,");
+X }
+X if ((fsdbuf [idx].fd_req.flags & M_NOEXEC) == M_NOEXEC)
+X {
+X strcat (diskInfo [idx].options, "noexec,");
+X }
+X
+X len = strlen (diskInfo [idx].options);
+X if (len > 0)
+X {
+X --len;
+X }
+X if (diskInfo [idx].options [len]==',')
+X {
+X diskInfo [idx].options [len] = '\0';
+X }
+X
+X if (debug > 1)
+X {
+X printf ("%s: %s\n", diskInfo [idx].name, diskInfo [idx].fsType);
+X printf ("\tblocks: tot:%ld free:%ld avail:%ld\n",
+X fsdbuf [idx].fd_btot, fsdbuf [idx].fd_bfree,
+X (int) fsdbuf [idx].fd_bfreen);
+X printf ("\tinodes: tot:%ld free:%ld\n",
+X fsdbuf [idx].fd_gtot, fsdbuf [idx].fd_gfree);
+X }
+X }
+X
+X free ((char *) fsdbuf);
+X return 0;
+X}
+X
+X/* this is a no-op; we have already done all the work */
+Xstatic void
+XgetDiskInfo ()
+X{
+X}
+X
+X#endif /* HAS_GETMNT */
+X
+X
+X#if defined (HAS_MNTCTL)
+X
+X/*
+X * getDiskEntries
+X *
+X * AIX V3.2 uses mntctl to find out about mounted file systems
+X *
+X */
+X
+X# define NUM_AIX_FSTYPES 6
+Xstatic char *AIX_fsType [NUM_AIX_FSTYPES] =
+X { "oaix", "", "nfs", "jfs", "", "cdrom" };
+X
+X/*
+X * from xfsm-1.80:
+X *
+X * MNT_AIX - "aix"
+X * MNT_NFS - "nfs"
+X * MNT_JFS - "jfs"
+X * MNT_CDROM - "cdrom"
+X * other - "user defined"
+X *
+X */
+X
+Xstatic int
+XgetDiskEntries ()
+X{
+X int num; /* number of vmount structs returned */
+X char *vmbuf; /* buffer for vmount structs returned */
+X int vmbufsz; /* size in bytes of vmbuf */
+X int i; /* index for looping and stuff */
+X char *bufp; /* pointer into vmbuf */
+X struct vmount *vmtp; /* pointer into vmbuf */
+X struct vfs_ent *ve; /* pointer for file system type entry */
+X int len;
+X
+X
+X i = 0;
+X vmbufsz = sizeof (struct vmount) * DI_FSMAGIC; /* initial vmount buffer */
+X
+X do
+X {
+X if ((vmbuf = (char *) malloc (vmbufsz)) == (char *) NULL)
+X {
+X fprintf (stderr, "malloc (%d) for mntctl() failed errno %d\n",
+X vmbufsz, errno);
+X return -1;
+X }
+X
+X num = mntctl (MCTL_QUERY, vmbufsz, vmbuf);
+X /*
+X * vmbuf is too small, could happen for
+X * following reasons:
+X * - inital buffer is too small
+X * - newly mounted file system
+X */
+X if (num == 0)
+X {
+X memcpy (&vmbufsz, vmbuf, sizeof (vmbufsz)); /* see mntctl(2) */
+X if (debug > 0)
+X {
+X printf ("vmbufsz too small, new size: %d\n", vmbufsz);
+X }
+X free ((char *) vmbuf); /* free this last, it's still being used! */
+X ++i;
+X }
+X } while (num == 0 && i < DI_RETRY_COUNT);
+X
+X if (i >= DI_RETRY_COUNT)
+X {
+X free ((char *) vmbuf);
+X fprintf (stderr, "unable to allocate adequate buffer for mntctl\n");
+X return -1;
+X }
+X
+X switch (num)
+X {
+X /* error happened, probably null vmbuf */
+X case -1:
+X {
+X free ((char *) vmbuf);
+X fprintf (stderr,"%s errno %d\n", strerror (errno), errno);
+X return -1;
+X }
+X
+X /* 'num' vmount structs returned in vmbuf */
+X default:
+X {
+X diCount = num;
+X diskInfo = (DiskInfo *) calloc (sizeof (DiskInfo), diCount);
+X if (diskInfo == (DiskInfo *) NULL)
+X {
+X fprintf (stderr, "malloc failed for diskInfo. errno %d\n", errno);
+X return -1;
+X }
+X
+X bufp = vmbuf;
+X for (i = 0; i < num; i++)
+X {
+X vmtp = (struct vmount *) bufp;
+X diskInfo [i].printFlag = DI_OK;
+X diskInfo [i].isLocal = TRUE;
+X
+X strncpy (diskInfo [i].special,
+X (char *) vmt2dataptr (vmtp, VMT_OBJECT),
+X DI_SPEC_NAME_LEN);
+X strncpy (diskInfo [i].name,
+X (char *) vmt2dataptr (vmtp, VMT_STUB), DI_NAME_LEN);
+X
+X ve = getvfsbytype (vmtp->vmt_gfstype);
+X if (ve == (struct vfs_ent *) NULL || *ve->vfsent_name == '\0')
+X {
+X if (vmtp->vmt_gfstype >= 0 &&
+X (vmtp->vmt_gfstype < NUM_AIX_FSTYPES))
+X {
+X strncpy (diskInfo [i].fsType,
+X AIX_fsType [vmtp->vmt_gfstype], DI_TYPE_LEN);
+X }
+X }
+X else
+X {
+X strncpy (diskInfo [i].fsType, ve->vfsent_name, DI_TYPE_LEN);
+X }
+X
+X if ((vmtp->vmt_flags & MNT_READONLY) == MNT_READONLY)
+X {
+X strcat (diskInfo [i].options, "ro,");
+X }
+X else
+X {
+X strcat (diskInfo [i].options, "rw,");
+X }
+X if ((vmtp->vmt_flags & MNT_NOSUID) != MNT_NOSUID)
+X {
+X strcat (diskInfo [i].options, "suid,");
+X }
+X if ((vmtp->vmt_flags & MNT_REMOVABLE) == MNT_REMOVABLE)
+X {
+X strcat (diskInfo [i].options, "removable,");
+X }
+X if ((vmtp->vmt_flags & MNT_DEVICE) == MNT_DEVICE)
+X {
+X strcat (diskInfo [i].options, "device,");
+X }
+X if ((vmtp->vmt_flags & MNT_REMOTE) == MNT_REMOTE)
+X {
+X strcat (diskInfo [i].options, "remote,");
+X diskInfo [i].isLocal = FALSE;
+X }
+X if ((vmtp->vmt_flags & MNT_UNMOUNTING) == MNT_UNMOUNTING)
+X {
+X strcat (diskInfo [i].options, "unmounting,");
+X }
+X if ((vmtp->vmt_flags & MNT_SYSV_MOUNT) == MNT_SYSV_MOUNT)
+X {
+X strcat (diskInfo [i].options, "sysv mount,");
+X }
+X if ((vmtp->vmt_flags & MNT_NODEV) == MNT_NODEV)
+X {
+X strcat (diskInfo [i].options, "nodev,");
+X }
+X
+X /* remove trailing comma */
+X len = strlen (diskInfo [i].options);
+X if (len > 0)
+X {
+X --len;
+X }
+X if (diskInfo [i].options [len] == ',')
+X {
+X diskInfo [i].options [len] = '\0';
+X }
+X
+X strncpy (diskInfo [i].mountTime, ctime (&vmtp->vmt_time),
+X DI_MNT_TIME_LEN);
+X
+X if (diskInfo [i].isLocal == FALSE &&
+X (flags & DI_F_LOCAL_ONLY) == DI_F_LOCAL_ONLY)
+X {
+X diskInfo [i].printFlag = DI_IGNORE;
+X if (debug > 2)
+X {
+X printf ("mnt: ignore: remote: %s\n",
+X diskInfo [i].name);
+X }
+X }
+X
+X bufp += vmtp->vmt_length;
+X }
+X
+X if (debug > 0)
+X {
+X printf ("mnt:%s - %s : %s\n", diskInfo [i].name,
+X diskInfo [i].special, diskInfo [i].fsType);
+X printf ("\t%s\n", (char *) vmt2dataptr (vmtp, VMT_ARGS));
+X }
+X
+X break;
+X } /* valid value returned */
+X } /* switch on num */
+X}
+X
+X#endif /* HAS_MNTCTL */
+X
+X
+X#if defined (HAS_STATVFS)
+X
+X/*
+X * getDiskInfo
+X *
+X * SysV.4. statvfs () returns both the free and available blocks.
+X *
+X */
+X
+Xstatic void
+XgetDiskInfo ()
+X{
+X int i;
+X double mult;
+X struct statvfs statBuf;
+X
+X for (i = 0; i < diCount; ++i)
+X {
+X if (diskInfo [i].isLocal == FALSE &&
+X (flags & DI_F_LOCAL_ONLY) == DI_F_LOCAL_ONLY)
+X {
+X diskInfo [i].printFlag = DI_IGNORE;
+X if (debug > 2)
+X {
+X printf ("mnt: ignore: remote: %s\n",
+X diskInfo [i].name);
+X }
+X }
+X
+X if (diskInfo [i].printFlag == DI_OK || (flags & DI_F_ALL) == DI_F_ALL)
+X {
+X if (statvfs (diskInfo [i].name, &statBuf) == 0)
+X {
+X /* data general DG/UX 5.4R3.00 sometime returns 0 */
+X /* in the fragment size field. */
+X if (statBuf.f_frsize == 0 && statBuf.f_bsize != 0)
+X {
+X mult = (double) (long) statBuf.f_bsize / dispBlockSize;
+X }
+X else
+X {
+X mult = (double) (long) statBuf.f_frsize / dispBlockSize;
+X }
+X
+X diskInfo [i].totalBlocks = ((double) (_s_fs_size_t) statBuf.f_blocks * mult);
+X diskInfo [i].freeBlocks = ((double) (_s_fs_size_t) statBuf.f_bfree * mult);
+X diskInfo [i].availBlocks = ((double) (_s_fs_size_t) statBuf.f_bavail * mult);
+X
+X diskInfo [i].totalInodes = statBuf.f_files;
+X diskInfo [i].freeInodes = statBuf.f_ffree;
+X diskInfo [i].availInodes = statBuf.f_favail;
+X
+X#if defined (HAS_STATVFS_BASETYPE)
+X strncpy (diskInfo [i].fsType, statBuf.f_basetype, DI_TYPE_LEN);
+X#endif
+X
+X if (debug > 1)
+X {
+X printf ("%s: %s\n", diskInfo [i].name, diskInfo [i].fsType);
+X printf ("\tmult:%f\n", mult);
+X printf ("\tbsize:%ld frsize:%ld\n", statBuf.f_bsize,
+X statBuf.f_frsize);
+X#if defined (HAS_64BIT_STATFS_FLDS)
+X printf ("\tblocks: tot:%llu free:%lld avail:%llu\n",
+X statBuf.f_blocks, statBuf.f_bfree, statBuf.f_bavail);
+X printf ("\tinodes: tot:%llu free:%lld avail:%llu\n",
+X statBuf.f_files, statBuf.f_ffree, statBuf.f_favail);
+X#else
+X printf ("\tblocks: tot:%lu free:%ld avail:%lu\n",
+X statBuf.f_blocks, statBuf.f_bfree, statBuf.f_bavail);
+X printf ("\tinodes: tot:%lu free:%ld avail:%lu\n",
+X statBuf.f_files, statBuf.f_ffree, statBuf.f_favail);
+X#endif
+X }
+X }
+X else
+X {
+X fprintf (stderr, "statvfs: %s ", diskInfo [i].name);
+X perror ("");
+X }
+X }
+X } /* for each entry */
+X}
+X
+X#endif /* HAS_STATVFS */
+X
+X
+X#if defined (HAS_STATFS_BSD) && ! defined (HAS_STATVFS) && \
+X ! defined (HAS_GETMNTINFO) && ! defined (HAS_GETMNT)
+X
+X/*
+X * getDiskInfo
+X *
+X * SunOS/BSD/Pyramid
+X *
+X */
+X
+Xstatic void
+XgetDiskInfo ()
+X{
+X int i;
+X double mult;
+X struct statfs statBuf;
+X
+X for (i = 0; i < diCount; ++i)
+X {
+X if (diskInfo [i].printFlag == DI_OK || (flags & DI_F_ALL) == DI_F_ALL)
+X {
+X if (statfs (diskInfo [i].name, &statBuf) == 0)
+X {
+X mult = (double) statBuf.f_bsize / dispBlockSize;
+X diskInfo [i].totalBlocks = ((double) (_s_fs_size_t) statBuf.f_blocks * mult);
+X diskInfo [i].freeBlocks = ((double) (_s_fs_size_t) statBuf.f_bfree * mult);
+X diskInfo [i].availBlocks = ((double) (_s_fs_size_t) statBuf.f_bavail * mult);
+X
+X diskInfo [i].totalInodes = statBuf.f_files;
+X diskInfo [i].freeInodes = statBuf.f_ffree;
+X diskInfo [i].availInodes = statBuf.f_ffree;
+X# if defined (HAS_SYSFS)
+X sysfs (GETFSTYP, statBuf.f_fstyp, diskInfo [i].fsType);
+X# endif
+X
+X if (debug > 1)
+X {
+X printf ("%s: %s\n", diskInfo [i].name, diskInfo [i].fsType);
+X printf ("\tmult:%f\n", mult);
+X printf ("\tbsize:%ld\n", statBuf.f_bsize);
+X printf ("\tblocks: tot:%ld free:%ld avail:%ld\n",
+X statBuf.f_blocks, statBuf.f_bfree, statBuf.f_bavail);
+X printf ("\tinodes: tot:%ld free:%ld\n",
+X statBuf.f_files, statBuf.f_ffree);
+X }
+X } /* if we got the info */
+X else
+X {
+X fprintf (stderr, "statfs: %s ", diskInfo [i].name);
+X perror ("");
+X }
+X }
+X } /* for each entry */
+X}
+X
+X#endif /* HAS_STATFS_BSD */
+X
+X#if defined (HAS_STATFS_SYSV3) && ! defined (HAS_STATVFS) && \
+X ! defined (HAS_GETMNTINFO) && ! defined (HAS_GETMNT)
+X
+X/*
+X * getDiskInfo
+X *
+X * SysV.3. We don't have available blocks; just set it to free blocks.
+X * The sysfs () call is used to get the disk type name.
+X *
+X */
+X
+Xstatic void
+XgetDiskInfo ()
+X{
+X int i;
+X double mult;
+X struct statfs statBuf;
+X
+X for (i = 0; i < diCount; ++i)
+X {
+X if (diskInfo [i].printFlag == DI_OK || (flags & DI_F_ALL) == DI_F_ALL)
+X {
+X if (statfs (diskInfo [i].name, &statBuf, sizeof (statBuf), 0) == 0)
+X {
+X# if defined (HAS_STATFS_FRSIZE)
+X if (statBuf.f_frsize == 0 && statBuf.f_bsize != 0)
+X {
+X mult = (double) (long) statBuf.f_bsize / dispBlockSize;
+X }
+X else
+X {
+X mult = (double) (long) statBuf.f_frsize / dispBlockSize;
+X }
+X# else
+X mult = (double) UBSIZE / dispBlockSize;
+X# endif
+X diskInfo [i].totalBlocks = ((double) (_s_fs_size_t) statBuf.f_blocks * mult);
+X diskInfo [i].freeBlocks = ((double) (_s_fs_size_t) statBuf.f_bfree * mult);
+X diskInfo [i].availBlocks = ((double) (_s_fs_size_t) statBuf.f_bfree * mult);
+X
+X diskInfo [i].totalInodes = statBuf.f_files;
+X diskInfo [i].freeInodes = statBuf.f_ffree;
+X diskInfo [i].availInodes = statBuf.f_ffree;
+X# if defined (HAS_SYSFS)
+X sysfs (GETFSTYP, statBuf.f_fstyp, diskInfo [i].fsType);
+X# endif
+X
+X if (debug > 1)
+X {
+X printf ("%s: %s\n", diskInfo [i].name, diskInfo [i].fsType);
+X printf ("\tmult:%f\n", mult);
+X# if defined (HAS_STATFS_FRSIZE)
+X printf ("\tbsize:%ld\n", statBuf.f_bsize);
+X printf ("\tfrsize:%ld\n", statBuf.f_frsize);
+X# else
+X printf ("\tUBSIZE:%ld\n", UBSIZE);
+X# endif
+X printf ("\tblocks: tot:%ld free:%ld\n",
+X statBuf.f_blocks, statBuf.f_bfree);
+X printf ("\tinodes: tot:%ld free:%ld\n",
+X statBuf.f_files, statBuf.f_ffree);
+X }
+X } /* if we got the info */
+X else
+X {
+X fprintf (stderr, "statfs: %s ", diskInfo [i].name);
+X perror ("");
+X }
+X }
+X } /* for each entry */
+X}
+X
+X#endif /* HAS_STATFS_SYSV3 */
+X
+X
+X#if defined (HAS_GETDISKFREESPACE)
+X
+X/*
+X * getDiskInfo
+X *
+X * Windows
+X *
+X */
+X
+X# define NUM_MSDOS_FSTYPES 7
+Xstatic char *MSDOS_diskType [NUM_MSDOS_FSTYPES] =
+X { "unknown", "", "removable", "fixed", "remote", "cdrom", "ramdisk" };
+X# define MSDOS_BUFFER_SIZE 128
+X# define BYTES_PER_LOGICAL_DRIVE 4
+X
+Xstatic int
+XgetDiskEntries ()
+X{
+X int i;
+X int diskflag;
+X int rc;
+X char *p;
+X char buff [MSDOS_BUFFER_SIZE];
+X
+X
+X diskflag = DI_IGNORE;
+X rc = GetLogicalDriveStrings (MSDOS_BUFFER_SIZE, buff);
+X diCount = rc / BYTES_PER_LOGICAL_DRIVE;
+X
+X diskInfo = (DiskInfo *) calloc (sizeof (DiskInfo), diCount);
+X if (diskInfo == (DiskInfo *) NULL)
+X {
+X fprintf (stderr, "malloc failed for diskInfo. errno %d\n", errno);
+X return -1;
+X }
+X
+X for (i = 0; i < diCount; ++i)
+X {
+X p = buff + (BYTES_PER_LOGICAL_DRIVE * i);
+X strncpy (diskInfo [i].name, p, DI_NAME_LEN);
+X rc = GetDriveType (p);
+X diskInfo [i].printFlag = DI_OK;
+X
+X if (rc == DRIVE_NO_ROOT_DIR)
+X {
+X diskInfo [i].printFlag = DI_BAD;
+X }
+X
+X /* assume that any removable drives before the */
+X /* first non-removable disk are floppies... */
+X else if (rc == DRIVE_REMOVABLE)
+X {
+X diskInfo [i].printFlag = diskflag;
+X }
+X else
+X {
+X diskflag = DI_OK;
+X }
+X
+X if (rc != DRIVE_REMOTE)
+X {
+X diskInfo [i].isLocal = TRUE;
+X }
+X /* strncpy (diskInfo [i].fsType, MSDOS_diskType [rc], DI_TYPE_LEN); */
+X } /* for each mounted drive */
+X
+X return diCount;
+X}
+X
+X/*
+X * getDiskInfo
+X *
+X * Windows
+X *
+X */
+X
+Xstatic void
+XgetDiskInfo ()
+X{
+X int i;
+X int rc;
+X double mult;
+X unsigned long sectorspercluster;
+X unsigned long bytespersector;
+X unsigned long totalclusters;
+X unsigned long freeclusters;
+X char tbuff [MSDOS_BUFFER_SIZE];
+X char volName [MSDOS_BUFFER_SIZE];
+X char fsName [MSDOS_BUFFER_SIZE];
+X DWORD serialNo;
+X DWORD maxCompLen;
+X DWORD fsFlags;
+X
+X
+X for (i = 0; i < diCount; ++i)
+X {
+X if (diskInfo [i].isLocal == FALSE &&
+X (flags & DI_F_LOCAL_ONLY) == DI_F_LOCAL_ONLY)
+X {
+X diskInfo [i].printFlag = DI_IGNORE;
+X if (debug > 2)
+X {
+X printf ("mnt: ignore: remote: %s\n",
+X diskInfo [i].name);
+X }
+X }
+X
+X if (diskInfo [i].printFlag == DI_OK || (flags & DI_F_ALL) == DI_F_ALL)
+X {
+X rc = GetVolumeInformation (diskInfo [i].name,
+X volName, MSDOS_BUFFER_SIZE, &serialNo, &maxCompLen,
+X &fsFlags, fsName, MSDOS_BUFFER_SIZE);
+X /* strcpy (tbuff, diskInfo [i].fsType); */
+X /* strcat (tbuff, " "); */
+X strncpy (diskInfo [i].fsType, fsName, DI_TYPE_LEN);
+X strncpy (diskInfo [i].special, volName, DI_SPEC_NAME_LEN);
+X
+X rc = GetDiskFreeSpace (diskInfo [i].name,
+X (LPDWORD) §orspercluster, (LPDWORD) &bytespersector,
+X (LPDWORD) &freeclusters, (LPDWORD) &totalclusters);
+X
+X if (rc > 0)
+X {
+X mult = (double) (sectorspercluster *
+X bytespersector) / dispBlockSize;
+X diskInfo [i].totalBlocks = ((double) (_s_fs_size_t) totalclusters * mult);
+X diskInfo [i].freeBlocks = ((double) (_s_fs_size_t) freeclusters * mult);
+X diskInfo [i].availBlocks = ((double) (_s_fs_size_t) freeclusters * mult);
+X
+X diskInfo [i].totalInodes = 0;
+X diskInfo [i].freeInodes = 0;
+X diskInfo [i].availInodes = 0;
+X
+X if (debug > 1)
+X {
+X printf ("%s: %s\n", diskInfo [i].name, diskInfo [i].fsType);
+X printf ("\ts/c:%ld b/s:%ld\n", sectorspercluster,
+X bytespersector);
+X printf ("\tmult:%f\n", mult);
+X printf ("\tclusters: tot:%ld free:%ld\n",
+X totalclusters, freeclusters);
+X }
+X }
+X else
+X {
+X diskInfo [i].printFlag = DI_BAD;
+X if (debug)
+X {
+X printf ("disk %s; could not get disk space\n",
+X diskInfo [i].name);
+X }
+X }
+X } /* if printable drive */
+X } /* for each mounted drive */
+X}
+X
+X#endif /* HAS_GETDISKFREESPACE */
+END_OF_FILE
+if test 97566 -ne `wc -c <'di.c'`; then
+ echo shar: \"'di.c'\" unpacked with wrong size!
+fi
+# end of 'di.c'
+fi
+echo shar: End of archive 2 \(of 3\).
+cp /dev/null ark2isdone
+MISSING=""
+for I in 1 2 3 ; do
+ if test ! -f ark${I}isdone ; then
+ MISSING="${MISSING} ${I}"
+ fi
+done
+if test "${MISSING}" = "" ; then
+ echo You have unpacked all 3 archives.
+ rm -f ark[1-9]isdone
+else
+ echo You still need to unpack the following archives:
+ echo " " ${MISSING}
+fi
+## End of shell archive.
+exit 0
+