/*
$Id: dilib.c,v 1.36 2007-05-30 10:26:44-07 bll Exp $
$Source: /export/home/bll/DI/RCS/dilib.c,v $
Copyright 1994-2007 Brad Lanam, Walnut Creek, CA
*/
/********************************************************/
/*
This module contains the system specific routines
to get the actual disk information.
di_getDiskEntries ()
Get a list of mounted filesystems.
di_testRemoteDisk ()
Checks the partitions to see if they are mounted
locally or not.
di_getDiskInfo
Gets the disk space used/available on the
partitions we want displayed.
To Do:
The following operating systems have
empty di_getDiskInfo() routines:
BeOS OSF/1 Ultrix
These need to be rewritten to separate
the fetch of mounted partition info, and
the fetch of disk space.
*/
/********************************************************/
#include "config.h"
#include "di.h"
#include <stdio.h>
#if _hdr_ctype
# include <ctype.h>
#endif
#if _hdr_errno
# include <errno.h>
#endif
#if _hdr_stdlib
# include <stdlib.h>
#endif
#if _sys_types
# include <sys/types.h>
#endif
#if _hdr_string
# include <string.h>
#endif
#if _hdr_strings && ((! defined (_hdr_string)) || (_include_string))
# include <strings.h>
#endif
#if _hdr_memory
# include <memory.h>
#endif
#if _include_malloc && _hdr_malloc
# include <malloc.h>
#endif
#if _hdr_unistd
# include <unistd.h>
#endif
#if _hdr_time
# include <time.h>
#endif
#if _sys_time
# include <sys/time.h>
#endif
#if _sys_stat
# include <sys/stat.h>
#endif
#if _sys_param
# include <sys/param.h>
#endif
#if _sys_mnttab
# include <sys/mnttab.h>
#endif
#if _hdr_mnttab
# include <mnttab.h>
#endif
#if _hdr_mntent
# include <mntent.h>
#endif
#if _sys_mntent
# include <sys/mntent.h>
#endif
#if _sys_mount
# include <sys/mount.h>
#endif
#if _sys_fstypes
# include <sys/fstypes.h>
#endif
#if _sys_fs_types
# include <sys/fs_types.h>
#endif
#if _sys_mntctl
# include <sys/mntctl.h>
#endif
#if _sys_vmount
# include <sys/vmount.h>
#endif
#if _sys_statfs && ! defined (_sys_statvfs)
# include <sys/statfs.h>
#endif
#if _hdr_fshelp
# include <fshelp.h>
#endif
#if _sys_statvfs
# include <sys/statvfs.h>
#endif
#if _sys_fstyp
# include <sys/fstyp.h>
# define DI_TYPE_LEN FSTYPSZ
#endif
#if _sys_vfs
# include <sys/vfs.h>
#endif
#if _sys_vfstab
# include <sys/vfstab.h>
# if ! defined (DI_TYPE_LEN)
# define DI_TYPE_LEN FSTYPSZ
# endif
#endif
#if _hdr_windows
# include <windows.h> /* windows */
#endif
#if _hdr_kernel_fs_info
# include <kernel/fs_info.h>
#endif
#if _hdr_storage_Directory
# include <storage/Directory.h>
#endif
#if _hdr_storage_Entry
# include <storage/Entry.h>
#endif
#if _hdr_storage_Path
# include <storage/Path.h>
#endif
/********************************************************/
/* remap mount flags */
# if defined (M_RDONLY)
# define MNT_RDONLY M_RDONLY
# endif
# if defined (MNT_READONLY)
# define MNT_RDONLY MNT_READONLY
# endif
# if defined (M_RONLY)
# define MNT_RDONLY M_RONLY
# endif
# if defined (M_SYNCHRONOUS)
# define MNT_SYNCHRONOUS M_SYNCHRONOUS
# endif
# if defined (M_NOEXEC)
# define MNT_NOEXEC M_NOEXEC
# endif
# if defined (M_NOSUID)
# define MNT_NOSUID M_NOSUID
# endif
# if defined (M_NODEV)
# define MNT_NODEV M_NODEV
# endif
# if defined (M_NOATIMES)
# define MNT_NOATIMES M_NOATIMES
# endif
# if defined (M_GRPID)
# define MNT_GRPID M_GRPID
# endif
# if defined (M_SECURE)
# define MNT_SECURE M_SECURE
# endif
# if defined (M_MLSD)
# define MNT_MLSD M_MLSD
# endif
# if defined (M_SMSYNC2)
# define MNT_SMSYNC2 M_SMSYNC2
# endif
# if defined (M_LOCAL)
# define MNT_LOCAL M_LOCAL
# endif
# if defined (M_FORCE)
# define MNT_FORCE M_FORCE
# endif
# if defined (M_SYNC)
# define MNT_SYNC M_SYNC
# endif
# if defined (M_NOCACHE)
# define MNT_NOCACHE M_NOCACHE
# endif
static void convertMountOptions _((long, diDiskInfo_t *));
static void convertNFSMountOptions _((long, long, long, diDiskInfo_t *));
static void trimChar _((char *, int));
#if _lib_getmntent && \
! defined (_lib_mntctl)
static char *chkMountOptions _((char *, char *));
#endif
/********************************************************/
#if (_lib_getmntent || \
_statfs_2arg || \
_statfs_3arg || \
_statfs_4arg) && \
! defined (_lib_getmntinfo) && \
! defined (_lib_getfsstat) && \
! defined (_lib_getvfsstat) && \
! defined (_lib_mntctl) && \
! defined (_lib_getmnt)
# if defined (MOUNTED)
# define DI_MOUNT_FILE MOUNTED
# else
# if defined (MNTTAB)
# define DI_MOUNT_FILE MNTTAB
# else
# if (USE_ETC_FILESYSTEMS)
# define DI_MOUNT_FILE "/etc/filesystems" /* AIX 4.x or /etc/mntent? */
# else
# define DI_MOUNT_FILE "/etc/mnttab"
# endif
# endif
# endif
#endif
#if ! defined (_lib_statvfs) && \
_lib_statfs && \
_npt_statfs
# if _statfs_2arg
extern int statfs _((char *, struct statfs *));
# endif
# if _statfs_3arg
extern int statfs _((char *, struct statfs *, int));
# endif
# if _statfs_4arg
extern int statfs _((char *, struct statfs *, int, int));
# endif
#endif
#if _statfs_4arg && \
! defined (_lib_statvfs) && \
! defined (_lib_getmntinfo) && \
! defined (_lib_getfsstat) && \
! defined (_lib_getvfsstat) && \
! defined (_lib_getmnt) /* SYSV.3 */
# if ! defined (UBSIZE)
# if defined (BSIZE)
# define UBSIZE BSIZE
# else
# define UBSIZE 512
# endif
# endif
#endif
/********************************************************/
#if defined (MNTOPT_IGNORE)
# define DI_MNTOPT_IGNORE MNTOPT_IGNORE
#else
# define DI_MNTOPT_IGNORE "ignore"
#endif
#if defined (MNTOPT_RO)
# define DI_MNTOPT_RO MNTOPT_RO
#else
# define DI_MNTOPT_RO "ro"
#endif
#if defined (MNTOPT_DEV)
# define DI_MNTOPT_DEV MNTOPT_DEV
#else
# define DI_MNTOPT_DEV "dev="
#endif
/********************************************************/
#define DI_UNKNOWN_FSTYPE "Unknown fstyp %.2d"
int di_lib_debug = { 0 };
#if _lib_fs_stat_dev
/*
* di_getDiskEntries
*
* For BeOS.
*
*/
int
# if _proto_stdc
di_getDiskEntries (diDiskInfo_t **diskInfo, int *diCount)
# else
di_getDiskEntries (diskInfo, diCount)
diDiskInfo_t **diskInfo;
int *diCount;
# endif
{
diDiskInfo_t *diptr;
status_t stat;
int idx;
int32 count;
dev_t dev;
char buff [B_FILE_NAME_LENGTH];
fs_info fsinfo;
node_ref nref;
BDirectory *dir;
BEntry entry;
BPath path;
if (di_lib_debug > 0) { printf ("# lib:getDiskEntries: fs_stat_dev\n"); }
count = 0;
while ((dev = next_dev (&count)) != B_BAD_VALUE)
{
if ((stat = fs_stat_dev (dev, &fsinfo)) == B_BAD_VALUE)
{
break;
}
idx = *diCount;
++*diCount;
*diskInfo = (diDiskInfo_t *) Realloc ((char *) *diskInfo,
sizeof (diDiskInfo_t) * *diCount);
diptr = *diskInfo + idx;
memset ((char *) diptr, '\0', sizeof (diDiskInfo_t));
diptr->printFlag = DI_PRNT_OK;
*buff = '\0';
nref.device = dev;
nref.node = fsinfo.root;
dir = new BDirectory (&nref);
stat = dir->GetEntry (&entry);
stat = entry.GetPath (&path);
strncpy (diptr->name, path.Path (), DI_NAME_LEN);
strncpy (diptr->special, fsinfo.device_name, DI_SPEC_NAME_LEN);
strncpy (diptr->fsType, fsinfo.fsh_name, DI_TYPE_LEN);
diptr->isLocal = TRUE;
diptr->isReadOnly = FALSE;
diptr->blockSize = (_fs_size_t) fsinfo.block_size;
diptr->totalBlocks = (_fs_size_t) fsinfo.total_blocks;
diptr->freeBlocks = (_fs_size_t) fsinfo.free_blocks;
diptr->availBlocks = (_fs_size_t) fsinfo.free_blocks;
diptr->totalInodes = fsinfo.total_nodes;
diptr->freeInodes = fsinfo.free_nodes;
diptr->availInodes = fsinfo.free_nodes;
if (di_lib_debug > 0)
{
printf ("mnt:%s - %s\n", diptr->name,
diptr->special);
printf ("dev:%d fs:%s\n", dev, diptr->fsType);
}
if (di_lib_debug > 1)
{
printf ("%s: %s\n", diptr->name, diptr->fsType);
printf ("\tblocks: tot:%ld free:%ld\n",
fsinfo.total_blocks, fsinfo.free_blocks);
printf ("\tinodes: tot:%ld free:%ld\n",
fsinfo.total_nodes, fsinfo.free_nodes);
}
}
return 0;
}
#endif
#if _lib_getmntent && \
! defined (_lib_setmntent) && \
! defined (_lib_mntctl)
/*
* di_getDiskEntries
*
* For SysV.4, we open the file and call getmntent () repeatedly.
*
*/
static char *checkMountOptions _((struct mnttab *, char *));
int
# if _proto_stdc
di_getDiskEntries (diDiskInfo_t **diskInfo, int *diCount)
# else
di_getDiskEntries (diskInfo, diCount)
diDiskInfo_t **diskInfo;
int *diCount;
# endif
{
diDiskInfo_t *diptr;
FILE *f;
int idx;
struct mnttab mntEntry;
time_t mtime;
char *devp; /* local ptr to dev entry */
if (di_lib_debug > 0) { printf ("# lib:getDiskEntries: _lib_getmntent\n"); }
if ((f = fopen (DI_MOUNT_FILE, "r")) == (FILE *) NULL)
{
fprintf (stderr, "Unable to open: %s errno %d\n", DI_MOUNT_FILE, errno);
return -1;
}
while (getmntent (f, &mntEntry) == 0)
{
idx = *diCount;
++*diCount;
*diskInfo = (diDiskInfo_t *) Realloc ((char *) *diskInfo,
sizeof (diDiskInfo_t) * *diCount);
diptr = *diskInfo + idx;
memset ((char *) diptr, '\0', sizeof (diDiskInfo_t));
diptr->printFlag = DI_PRNT_OK;
diptr->isLocal = TRUE;
diptr->isReadOnly = FALSE;
strncpy (diptr->special, mntEntry.mnt_special, DI_SPEC_NAME_LEN);
strncpy (diptr->name, mntEntry.mnt_mountp, DI_NAME_LEN);
if (checkMountOptions (&mntEntry, DI_MNTOPT_IGNORE) != (char *) NULL)
{
diptr->printFlag = DI_PRNT_IGNORE;
if (di_lib_debug > 2)
{
printf ("mnt: ignore: mntopt 'ignore': %s\n",
diptr->name);
}
}
if ((devp = checkMountOptions (&mntEntry, DI_MNTOPT_DEV)) !=
(char *) NULL)
{
if (devp != mntEntry.mnt_mntopts)
{
--devp;
}
*devp = 0; /* point to preceeding comma and cut off */
}
if (checkMountOptions (&mntEntry, DI_MNTOPT_RO) != (char *) NULL)
{
diptr->isReadOnly = TRUE;
}
strncpy (diptr->options, mntEntry.mnt_mntopts, DI_OPT_LEN);
mtime = atol (mntEntry.mnt_time);
strncpy (diptr->mountTime, ctime (&mtime), DI_MNT_TIME_LEN);
/* get the file system type now... */
strncpy (diptr->fsType, mntEntry.mnt_fstype, DI_TYPE_LEN);
if (di_lib_debug > 2)
{
printf ("mnt:%s - %s\n", diptr->name, diptr->fsType);
}
if (di_lib_debug > 0)
{
printf ("mnt:%s - %s\n", diptr->name, diptr->special);
}
}
fclose (f);
return 0;
}
static char *
# if _proto_stdc
checkMountOptions (struct mnttab *mntEntry, char *str)
# else
checkMountOptions (mntEntry, str)
struct mnttab *mntEntry;
char *str;
# endif
{
# if _lib_hasmntopt
return hasmntopt (mntEntry, str);
# else
return chkMountOptions (mntEntry->mnt_mntopts, str);
# endif
}
#endif /* _lib_getmntent */
#if _lib_getmntent && \
! defined (_lib_mntctl)
static char *
# if _proto_stdc
chkMountOptions (char *mntopts, char *str)
# else
chkMountOptions (mntopts, str)
char *mntopts;
char *str;
# endif
{
char *ptr;
char *tstr;
tstr = strdup (mntopts);
ptr = strtok (tstr, ",");
while (ptr != (char *) NULL)
{
if (strcmp (ptr, str) == 0)
{
free (tstr);
return ptr;
}
ptr = strtok ((char *) NULL, ",");
}
free (tstr);
return (char *) NULL;
}
#endif /* _lib_getmntent */
#if _lib_statvfs && \
! defined (_lib_getmntinfo) && \
! defined (_lib_getfsstat) && \
! defined (_lib_getvfsstat) && \
! defined (_lib_GetVolumeInformation)
/*
* di_getDiskInfo
*
* SysV.4. statvfs () returns both the free and available blocks.
*
*/
# define DI_GETDISKINFO_DEF 1
void
# if _proto_stdc
di_getDiskInfo (diDiskInfo_t **diskInfo, int *diCount)
# else
di_getDiskInfo (diskInfo, diCount)
diDiskInfo_t **diskInfo;
int *diCount;
# endif
{
diDiskInfo_t *diptr;
int i;
Statvfs_t statBuf;
if (di_lib_debug > 0) { printf ("# lib:getDiskInfo: statvfs\n"); }
for (i = 0; i < *diCount; ++i)
{
diptr = *diskInfo + i;
if (diptr->printFlag == DI_PRNT_OK)
{
if (statvfs (diptr->name, &statBuf) == 0)
{
/* data general DG/UX 5.4R3.00 sometime returns 0 */
/* in the fragment size field. */
if (statBuf.f_frsize == 0 && statBuf.f_bsize != 0)
{
diptr->blockSize = statBuf.f_bsize;
}
else
{
diptr->blockSize = statBuf.f_frsize;
}
/* Linux! statvfs() returns values in f_bsize rather f_frsize. Bleah. */
/* Non-POSIX! Linux manual pages are incorrect. */
# if linux
diptr->blockSize = statBuf.f_bsize;
# endif /* linux */
diptr->totalBlocks = (_fs_size_t) statBuf.f_blocks;
diptr->freeBlocks = (_fs_size_t) statBuf.f_bfree;
diptr->availBlocks = (_fs_size_t) statBuf.f_bavail;
diptr->totalInodes = (_fs_size_t) statBuf.f_files;
diptr->freeInodes = (_fs_size_t) statBuf.f_ffree;
diptr->availInodes = (_fs_size_t) statBuf.f_favail;
if (di_lib_debug > 1)
{
printf ("%s: %s\n", diptr->name, diptr->fsType);
printf ("\tbsize:%ld frsize:%ld\n", (long) statBuf.f_bsize,
(long) statBuf.f_frsize);
#if _siz_long_long >= 8
printf ("\tblocks: tot:%llu free:%lld avail:%llu\n",
statBuf.f_blocks, statBuf.f_bfree, statBuf.f_bavail);
printf ("\tinodes: tot:%llu free:%llu avail:%llu\n",
statBuf.f_files, statBuf.f_ffree, statBuf.f_favail);
#else
printf ("\tblocks: tot:%lu free:%lu avail:%lu\n",
statBuf.f_blocks, statBuf.f_bfree, statBuf.f_bavail);
printf ("\tinodes: tot:%lu free:%lu avail:%lu\n",
statBuf.f_files, statBuf.f_ffree, statBuf.f_favail);
#endif
}
}
else
{
fprintf (stderr, "statvfs: %s ", diptr->name);
perror ("");
}
}
} /* for each entry */
}
#endif /* _lib_statvfs */
#if ! defined (_lib_getmntent) && \
! defined (_lib_mntctl) && \
! defined (_lib_getmntinfo) && \
! defined (_lib_getfsstat) && \
! defined (_lib_getvfsstat) && \
! defined (_lib_getmnt) && \
! defined (_lib_GetDiskFreeSpace) && \
! defined (_lib_GetDiskFreeSpaceEx) && \
! defined (_lib_fs_stat_dev)
/*
* di_getDiskEntries
*
* For SysV.3 we open the file and read it ourselves.
*
*/
int
# if _proto_stdc
di_getDiskEntries (diDiskInfo_t **diskInfo, int *diCount)
# else
di_getDiskEntries (diskInfo, diCount)
diDiskInfo_t **diskInfo;
int *diCount;
# endif
{
FILE *f;
int idx;
struct mnttab mntEntry;
if (di_lib_debug > 0) { printf ("# lib:getDiskEntries: not anything; sys v.3\n"); }
if ((f = fopen (DI_MOUNT_FILE, "r")) == (FILE *) NULL)
{
fprintf (stderr, "Unable to open: %s errno %d\n", DI_MOUNT_FILE, errno);
return -1;
}
while (fread ((char *) &mntEntry, sizeof (struct mnttab), 1, f) == 1)
{
/* xenix allows null mount table entries */
/* sco nfs background mounts are marked as "nothing" */
if (mntEntry.mt_filsys [0] &&
strcmp (mntEntry.mt_filsys, "nothing") != 0)
{
idx = *diCount;
++*diCount;
*diskInfo = (diDiskInfo_t *) Realloc ((char *) *diskInfo,
sizeof (diDiskInfo_t) * *diCount);
memset ((char *) diptr, '\0', sizeof (diDiskInfo_t));
diptr->printFlag = DI_PRNT_OK;
diptr->isLocal = TRUE;
diptr->isReadOnly = FALSE;
# if defined (COHERENT)
/* Coherent seems to have these fields reversed. oh well. */
strncpy (diptr->name, mntEntry.mt_dev, DI_NAME_LEN);
strncpy (diptr->special, mntEntry.mt_filsys, DI_SPEC_NAME_LEN);
# else
strncpy (diptr->special, mntEntry.mt_dev, DI_SPEC_NAME_LEN);
strncpy (diptr->name, mntEntry.mt_filsys, DI_NAME_LEN);
# endif
strncpy (diptr->options, mntEntry.mnt_mntopts, DI_OPT_LEN);
strncpy (diptr->mountTime, mntEntry.mnt_time,
DI_MNT_TIME_LEN);
}
if (di_lib_debug > 0)
{
printf ("mnt:%s - %s\n", diptr->name,
diptr->special);
}
}
fclose (f);
return 0;
}
#endif /* Sys V.3 */
#if _statfs_4arg && \
! defined (_lib_statvfs) && \
! defined (_lib_getmntinfo) && \
! defined (_lib_getfsstat) && \
! defined (_lib_getvfsstat) && \
! defined (_lib_getmnt)
/*
* di_getDiskInfo
*
* SysV.3. We don't have available blocks; just set it to free blocks.
* The sysfs () call is used to get the disk type name.
*
*/
# define DI_GETDISKINFO_DEF 1
void
# if _proto_stdc
di_getDiskInfo (diDiskInfo_t **diskInfo, int *diCount)
# else
di_getDiskInfo (diskInfo, diCount)
diDiskInfo_t **diskInfo;
int *diCount;
# endif
{
diDiskInfo_t *diptr;
int i;
struct statfs statBuf;
if (di_lib_debug > 0) { printf ("# lib:getDiskInfo: sysv-statfs 4arg\n"); }
for (i = 0; i < *diCount; ++i)
{
diptr = *diskInfo + i;
if (diptr->printFlag == DI_PRNT_OK)
{
if (statfs (diptr->name, &statBuf, sizeof (statBuf), 0) == 0)
{
# if _mem_f_frsize_statfs
if (statBuf.f_frsize == 0 && statBuf.f_bsize != 0)
{
diptr->blockSize = (_fs_size_t) statBuf.f_bsize;
}
else
{
diptr->blockSize = (_fs_size_t) statBuf.f_frsize;
}
# else
diptr->blockSize = UBSIZE;
# endif
diptr->totalBlocks = (_fs_size_t) statBuf.f_blocks;
diptr->freeBlocks = (_fs_size_t) statBuf.f_bfree;
diptr->availBlocks = (_fs_size_t) statBuf.f_bfree;
diptr->totalInodes = statBuf.f_files;
diptr->freeInodes = statBuf.f_ffree;
diptr->availInodes = statBuf.f_ffree;
# if _lib_sysfs
sysfs (GETFSTYP, statBuf.f_fstyp, diptr->fsType);
# endif
if (di_lib_debug > 1)
{
printf ("%s: %s\n", diptr->name, diptr->fsType);
# if _mem_f_frsize_statfs
printf ("\tbsize:%ld\n", statBuf.f_bsize);
printf ("\tfrsize:%ld\n", statBuf.f_frsize);
# else
printf ("\tUBSIZE:%ld\n", UBSIZE);
# endif
printf ("\tblocks: tot:%ld free:%ld\n",
statBuf.f_blocks, statBuf.f_bfree);
printf ("\tinodes: tot:%ld free:%ld\n",
statBuf.f_files, statBuf.f_ffree);
}
} /* if we got the info */
else
{
fprintf (stderr, "statfs: %s ", diptr->name);
perror ("");
}
}
} /* for each entry */
}
#endif /* _statfs_4arg */
#if _lib_getmntent && \
_lib_setmntent && \
_lib_endmntent && \
! defined (_lib_mntctl) && \
! defined (_lib_GetDiskFreeSpace) && \
! defined (_lib_GetDiskFreeSpaceEx)
/*
* di_getDiskEntries
*
* SunOS supplies an open and close routine for the mount table.
*
*/
#if ! defined (MNTTYPE_IGNORE)
# define MNTTYPE_IGNORE "ignore"
#endif
int
# if _proto_stdc
di_getDiskEntries (diDiskInfo_t **diskInfo, int *diCount)
# else
di_getDiskEntries (diskInfo, diCount)
diDiskInfo_t **diskInfo;
int *diCount;
# endif
{
diDiskInfo_t *diptr;
FILE *f;
int idx;
struct mntent *mntEntry;
char *devp; /* local ptr to dev entry */
if (di_lib_debug > 0) { printf ("# lib:getDiskEntries: get/set/endmntent\n"); }
#if _setmntent_1arg || ! defined (_setmntent_2arg)
if ((f = setmntent (DI_MOUNT_FILE)) == (FILE *) NULL)
#else
if ((f = setmntent (DI_MOUNT_FILE, "r")) == (FILE *) NULL)
#endif
{
fprintf (stderr, "Unable to open: %s errno %d\n", DI_MOUNT_FILE, errno);
return -1;
}
while ((mntEntry = getmntent (f)) != (struct mntent *) NULL)
{
idx = *diCount;
++*diCount;
*diskInfo = (diDiskInfo_t *) Realloc ((char *) *diskInfo,
sizeof (diDiskInfo_t) * *diCount);
diptr = *diskInfo + idx;
memset ((char *) diptr, '\0', sizeof (diDiskInfo_t));
diptr->printFlag = DI_PRNT_OK;
diptr->isLocal = TRUE;
diptr->isReadOnly = FALSE;
strncpy (diptr->special, mntEntry->mnt_fsname, DI_SPEC_NAME_LEN);
strncpy (diptr->name, mntEntry->mnt_dir, DI_NAME_LEN);
strncpy (diptr->fsType, mntEntry->mnt_type, DI_TYPE_LEN);
if (strcmp (mntEntry->mnt_fsname, "none") == 0)
{
diptr->printFlag = DI_PRNT_IGNORE;
if (di_lib_debug > 2)
{
printf ("mnt: ignore: fstype 'none': %s\n",
diptr->name);
}
}
if (strcmp (mntEntry->mnt_type, MNTTYPE_IGNORE) == 0)
{
diptr->printFlag = DI_PRNT_IGNORE;
if (di_lib_debug > 2)
{
printf ("mnt: ignore: mntopt 'ignore': %s\n",
diptr->name);
}
}
if ((devp = strstr (mntEntry->mnt_opts, "dev=")) != (char *) NULL)
{
if (devp != mntEntry->mnt_opts)
{
--devp;
}
*devp = 0; /* point to preceeding comma and cut off */
}
if (chkMountOptions (mntEntry->mnt_opts, DI_MNTOPT_RO) != (char *) NULL)
{
diptr->isReadOnly = TRUE;
}
strncpy (diptr->options, mntEntry->mnt_opts, DI_OPT_LEN);
if (di_lib_debug > 0)
{
printf ("mnt:%s - %s : %s\n", diptr->name,
diptr->special, diptr->fsType);
}
}
endmntent (f);
return 0;
}
#endif /* _lib_getmntent && _lib_setmntent && _lib_endmntent */
#if _lib_getmntinfo && \
! defined (_lib_getfsstat) && \
! defined (_lib_getvfsstat)
/*
* di_getDiskEntries
*
* Old OSF/1 system call...
* OSF/1 does this with a system call and library routine
*
* [mogul@wrl.dec.com (Jeffrey Mogul)]
*/
# if defined (INITMOUNTNAMES)
static char *mnt_names [] = INITMOUNTNAMES;
# define MNT_NUMTYPES (MOUNT_MAXTYPE + 1)
# endif
int
# if _proto_stdc
di_getDiskEntries (diDiskInfo_t **diskInfo, int *diCount)
# else
di_getDiskEntries (diskInfo, diCount)
diDiskInfo_t **diskInfo;
int *diCount;
# endif
{
diDiskInfo_t *diptr;
int count;
int idx;
int len;
short fstype;
struct statfs *mntbufp;
if (di_lib_debug > 0) { printf ("# lib:getDiskEntries: getmntinfo\n"); }
count = getmntinfo (&mntbufp, MNT_WAIT);
if (count < 1)
{
fprintf (stderr, "Unable to do getmntinfo () errno %d\n", errno);
return -1;
}
*diCount = count;
*diskInfo = (diDiskInfo_t *) malloc (sizeof (diDiskInfo_t) * count);
if (*diskInfo == (diDiskInfo_t *) NULL)
{
fprintf (stderr, "malloc failed for diskInfo. errno %d\n", errno);
return -1;
}
memset ((char *) *diskInfo, '\0', sizeof (diDiskInfo_t) * count);
if (di_lib_debug > 1)
{
printf ("type_len %d name_len %d spec_name_len %d\n", DI_TYPE_LEN,
DI_NAME_LEN, DI_SPEC_NAME_LEN);
}
for (idx = 0; idx < count; idx++)
{
diptr = *diskInfo + idx;
diptr->printFlag = DI_PRNT_OK;
diptr->isLocal = FALSE;
diptr->isReadOnly = FALSE;
# if defined (MNT_LOCAL)
if ((mntbufp [idx].f_flags & MNT_LOCAL) == MNT_LOCAL)
{
diptr->isLocal = TRUE;
}
# endif
strncpy (diptr->special, mntbufp [idx].f_mntfromname,
DI_SPEC_NAME_LEN);
strncpy (diptr->name, mntbufp [idx].f_mntonname, DI_NAME_LEN);
diptr->blockSize = (_fs_size_t) 1024;
# if _mem_f_fsize_statfs /* 1.x */
diptr->blockSize = (_fs_size_t) mntbufp [idx].f_fsize;
# endif
# if _mem_f_bsize_statfs /* 2.x */
diptr->blockSize = (_fs_size_t) mntbufp [idx].f_bsize;
# endif
diptr->totalBlocks = (_fs_size_t) mntbufp [idx].f_blocks;
diptr->freeBlocks = (_fs_size_t) mntbufp [idx].f_bfree;
diptr->availBlocks = (_fs_size_t) mntbufp [idx].f_bavail;
diptr->totalInodes = mntbufp [idx].f_files;
diptr->freeInodes = mntbufp [idx].f_ffree;
diptr->availInodes = mntbufp [idx].f_ffree;
fstype = mntbufp [idx].f_type;
# if ! defined (_sys_fstyp) && ! defined (INITMOUNTNAMES) && \
! defined (_mem_f_fstypename_statfs)
if ((fstype >= 0) && (fstype <= MOUNT_MAXTYPE))
{
switch (fstype)
{
# if defined (MOUNT_NONE)
case MOUNT_NONE: /* No Filesystem */
{
strncpy (diptr->fsType, "none", DI_TYPE_LEN);
break;
}
# endif
# if defined (MOUNT_UFS)
case MOUNT_UFS: /* UNIX "Fast" Filesystem */
{
strncpy (diptr->fsType, "ufs", DI_TYPE_LEN);
break;
}
# endif
# if defined (MOUNT_NFS)
case MOUNT_NFS: /* Network Filesystem */
{
strncpy (diptr->fsType, "nfs", DI_TYPE_LEN);
break;
}
# endif
# if defined (MOUNT_MFS)
case MOUNT_MFS: /* Memory Filesystem */
{
strncpy (diptr->fsType, "mfs", DI_TYPE_LEN);
break;
}
# endif
# if defined (MOUNT_MSDOS)
case MOUNT_MSDOS: /* MSDOS Filesystem */
{
strncpy (diptr->fsType, "msdos", DI_TYPE_LEN);
break;
}
# endif
# if defined (MOUNT_LFS)
case MOUNT_LFS:
{
strncpy (diptr->fsType, "lfs", DI_TYPE_LEN);
break;
}
# endif
# if defined (MOUNT_LOFS)
case MOUNT_LOFS:
{
strncpy (diptr->fsType, "lofs", DI_TYPE_LEN);
break;
}
# endif
# if defined (MOUNT_FDESC)
case MOUNT_FDESC:
{
strncpy (diptr->fsType, "fdesc", DI_TYPE_LEN);
break;
}
# endif
# if defined (MOUNT_PORTAL)
case MOUNT_PORTAL:
{
strncpy (diptr->fsType, "portal", DI_TYPE_LEN);
break;
}
# endif
# if defined (MOUNT_NULL)
case MOUNT_NULL:
{
strncpy (diptr->fsType, "null", DI_TYPE_LEN);
break;
}
# endif
# if defined (MOUNT_UMAP)
case MOUNT_UMAP:
{
strncpy (diptr->fsType, "umap", DI_TYPE_LEN);
break;
}
# endif
# if defined (MOUNT_KERNFS)
case MOUNT_KERNFS:
{
strncpy (diptr->fsType, "kernfs", DI_TYPE_LEN);
break;
}
# endif
# if defined (MOUNT_PROCFS)
case MOUNT_PROCFS: /* proc filesystem */
{
strncpy (diptr->fsType, "pfs", DI_TYPE_LEN);
break;
}
# endif
# if defined (MOUNT_AFS)
case MOUNT_AFS:
{
strncpy (diptr->fsType, "afs", DI_TYPE_LEN);
break;
}
# endif
# if defined (MOUNT_ISOFS)
case MOUNT_ISOFS: /* iso9660 cdrom */
{
strncpy (diptr->fsType, "iso9660fs", DI_TYPE_LEN);
break;
}
# endif
# if defined (MOUNT_ISO9660) && ! defined (MOUNT_CD9660)
case MOUNT_ISO9660: /* iso9660 cdrom */
{
strncpy (diptr->fsType, "iso9660", DI_TYPE_LEN);
break;
}
# endif
# if defined (MOUNT_CD9660)
case MOUNT_CD9660: /* iso9660 cdrom */
{
strncpy (diptr->fsType, "cd9660", DI_TYPE_LEN);
break;
}
# endif
# if defined (MOUNT_UNION)
case MOUNT_UNION:
{
strncpy (diptr->fsType, "union", DI_TYPE_LEN);
break;
}
# endif
} /* switch on mount type */
}
# else
# if _mem_f_fstypename_statfs
strncpy (diptr->fsType, mntbufp [idx].f_fstypename, DI_TYPE_LEN);
# else
/* could use getvfsbytype here... */
if ((fstype >= 0) && (fstype < MNT_NUMTYPES))
{
strncpy (diptr->fsType, mnt_names [fstype], DI_TYPE_LEN);
}
else
{
Snprintf (SPF(diptr->fsType, sizeof (diptr->fsType),
DI_UNKNOWN_FSTYPE), fstype);
}
# endif
# endif /* has fs_types.h */
diptr->isReadOnly = FALSE;
# if defined (MNT_RDONLY)
if ((mntbufp [idx].f_flags & MNT_RDONLY) == MNT_RDONLY)
{
diptr->isReadOnly = TRUE;
}
# endif
convertMountOptions ((long) mntbufp [idx].f_flags, diptr);
trimChar (diptr->options, ',');
if (di_lib_debug > 1)
{
printf ("%s: %s\n", diptr->name, diptr->fsType);
printf ("\tblocks: tot:%ld free:%ld avail:%ld\n",
mntbufp [idx].f_blocks, mntbufp [idx].f_bfree,
mntbufp [idx].f_bavail);
# if _mem_f_fsize_statfs
printf ("\tfsize:%ld \n", mntbufp [idx].f_fsize);
# endif
# if _mem_f_bsize_statfs
printf ("\tbsize:%ld \n", mntbufp [idx].f_bsize);
# endif
# if _mem_f_iosize_statfs
printf ("\tiosize:%ld \n", mntbufp [idx].f_iosize);
# endif
printf ("\tinodes: tot:%ld free:%ld\n",
mntbufp [idx].f_files, mntbufp [idx].f_ffree);
}
}
free ((char *) mntbufp); /* man page says this can't be freed. */
/* is it ok to try? */
return 0;
}
#endif /* _lib_getmntinfo */
#if _lib_getfsstat && \
! defined (_lib_getvfsstat)
/*
* di_getDiskEntries
*
* OSF/1 / Digital Unix / Compaq Tru64 / FreeBSD
*
*/
int
# if _proto_stdc
di_getDiskEntries (diDiskInfo_t **diskInfo, int *diCount)
# else
di_getDiskEntries (diskInfo, diCount)
diDiskInfo_t **diskInfo;
int *diCount;
# endif
{
diDiskInfo_t *diptr;
int count;
int idx;
long bufsize;
struct statfs *mntbufp;
struct statfs *sp;
if (di_lib_debug > 0) { printf ("# lib:getDiskEntries: getfsstat\n"); }
count = getfsstat ((struct statfs *) NULL, 0, MNT_NOWAIT);
if (count < 1)
{
fprintf (stderr, "Unable to do getfsstat () errno %d\n", errno);
return -1;
}
bufsize = sizeof (struct statfs) * count;
mntbufp = malloc (bufsize);
memset ((char *) mntbufp, '\0', sizeof (struct statfs) * count);
count = getfsstat (mntbufp, bufsize, MNT_NOWAIT);
*diCount = count;
*diskInfo = (diDiskInfo_t *) malloc (sizeof (diDiskInfo_t) * count);
if (*diskInfo == (diDiskInfo_t *) NULL)
{
fprintf (stderr, "malloc failed for diskInfo. errno %d\n", errno);
return -1;
}
memset ((char *) *diskInfo, '\0', sizeof (diDiskInfo_t) * count);
for (idx = 0; idx < count; idx++)
{
diptr = *diskInfo + idx;
diptr->printFlag = DI_PRNT_OK;
diptr->isLocal = FALSE;
diptr->isReadOnly = FALSE;
# if defined (MNT_RDONLY)
if ((mntbufp [idx].f_flags & MNT_RDONLY) == MNT_RDONLY)
{
diptr->isReadOnly = TRUE;
}
# endif
# if defined (MNT_LOCAL)
if ((mntbufp [idx].f_flags & MNT_LOCAL) == MNT_LOCAL)
{
diptr->isLocal = TRUE;
}
# endif
sp = mntbufp + idx;
convertMountOptions ((long) sp->f_flags, diptr);
# if _mem_f_type_statfs
# if defined (MOUNT_NFS3)
if (sp->f_type == MOUNT_NFS3)
{
strncat (diptr->options, "v3,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
# endif
# endif
# if _mem_mount_info_statfs && \
defined (MOUNT_NFS) && \
(_mem_f_type_statfs || _mem_f_fstypename_statfs)
# if _mem_f_type_statfs
if (sp->f_type == MOUNT_NFS
# endif
# if _mem_f_fstypename_statfs
if (strcmp (sp->f_fstypename, MOUNT_NFS) == 0
# endif
# if _mem_f_fstypename_statfs && defined (MOUNT_NFS3)
|| strcmp (sp->f_fstypename, MOUNT_NFS3) == 0
# endif
# if _mem_f_type_statfs && defined (MOUNT_NFS3)
|| sp->f_type == MOUNT_NFS3
# endif
)
{
struct nfs_args *na;
na = &sp->mount_info.nfs_args;
convertNFSMountOptions (na->flags, na->wsize, na->rsize, diptr);
}
# endif
trimChar (diptr->options, ',');
strncpy (diptr->special, sp->f_mntfromname, DI_SPEC_NAME_LEN);
strncpy (diptr->name, sp->f_mntonname, DI_NAME_LEN);
# if _mem_f_fsize_statfs
diptr->blockSize = (_fs_size_t) mntbufp [idx].f_fsize;
# endif
# if _mem_f_bsize_statfs && ! defined (_mem_f_fsize_statfs)
diptr->blockSize = (_fs_size_t) mntbufp [idx].f_bsize;
# endif
diptr->totalBlocks = (_fs_size_t) sp->f_blocks;
diptr->freeBlocks = (_fs_size_t) sp->f_bfree;
diptr->availBlocks = (_fs_size_t) sp->f_bavail;
diptr->totalInodes = sp->f_files;
diptr->freeInodes = sp->f_ffree;
diptr->availInodes = sp->f_ffree;
# if _mem_f_fstypename_statfs
strncpy (diptr->fsType, sp->f_fstypename, DI_TYPE_LEN);
# else
# if _lib_sysfs && _mem_f_type_statfs
sysfs (GETFSTYP, sp->f_type, diptr->fsType);
# endif
# endif
}
free ((char *) mntbufp);
return 0;
}
#endif /* _lib_getfsstat */
#if _lib_getvfsstat
/*
* di_getDiskEntries
*
* NetBSD
*
*/
int
# if _proto_stdc
di_getDiskEntries (diDiskInfo_t **diskInfo, int *diCount)
# else
di_getDiskEntries (diskInfo, diCount)
diDiskInfo_t **diskInfo;
int *diCount;
# endif
{
diDiskInfo_t *diptr;
int count;
int idx;
long bufsize;
struct statvfs *mntbufp;
struct statvfs *sp;
if (di_lib_debug > 0) { printf ("# lib:getDiskEntries: getvfsstat\n"); }
count = getvfsstat ((struct statvfs *) NULL, 0, ST_NOWAIT);
if (count < 1)
{
fprintf (stderr, "Unable to do getvfsstat () errno %d\n", errno);
return -1;
}
bufsize = sizeof (struct statvfs) * count;
mntbufp = malloc (bufsize);
memset ((char *) mntbufp, '\0', sizeof (struct statvfs) * count);
count = getvfsstat (mntbufp, bufsize, ST_NOWAIT);
*diCount = count;
*diskInfo = (diDiskInfo_t *) malloc (sizeof (diDiskInfo_t) * count);
if (*diskInfo == (diDiskInfo_t *) NULL)
{
fprintf (stderr, "malloc failed for diskInfo. errno %d\n", errno);
return -1;
}
memset ((char *) *diskInfo, '\0', sizeof (diDiskInfo_t) * count);
for (idx = 0; idx < count; idx++)
{
diptr = *diskInfo + idx;
diptr->printFlag = DI_PRNT_OK;
diptr->isLocal = FALSE;
diptr->isReadOnly = FALSE;
sp = mntbufp + idx;
# if defined (MNT_RDONLY)
if ((sp->f_flag & MNT_RDONLY) == MNT_RDONLY)
{
diptr->isReadOnly = TRUE;
}
# endif
# if defined (MNT_LOCAL)
if ((sp->f_flag & MNT_LOCAL) == MNT_LOCAL)
{
diptr->isLocal = TRUE;
}
# endif
convertMountOptions ((long) sp->f_flag, diptr);
trimChar (diptr->options, ',');
if (sp->f_frsize == 0 && sp->f_bsize != 0)
{
diptr->blockSize = (_fs_size_t) sp->f_bsize;
}
else
{
diptr->blockSize = (_fs_size_t) sp->f_frsize;
}
diptr->totalBlocks = (_fs_size_t) sp->f_blocks;
diptr->freeBlocks = (_fs_size_t) sp->f_bfree;
diptr->availBlocks = (_fs_size_t) sp->f_bavail;
diptr->totalInodes = sp->f_files;
diptr->freeInodes = sp->f_ffree;
diptr->availInodes = sp->f_ffree;
strncpy (diptr->special, sp->f_mntfromname, DI_SPEC_NAME_LEN);
strncpy (diptr->name, sp->f_mntonname, DI_NAME_LEN);
strncpy (diptr->fsType, sp->f_fstypename, DI_TYPE_LEN);
if (di_lib_debug > 1)
{
printf ("%s: %s\n", diptr->name, diptr->fsType);
printf ("\tbsize:%ld frsize:%ld\n", (long) sp->f_bsize,
(long) sp->f_frsize);
#if _siz_long_long >= 8
printf ("\tblocks: tot:%llu free:%lld avail:%llu\n",
sp->f_blocks, sp->f_bfree, sp->f_bavail);
printf ("\tinodes: tot:%llu free:%llu avail:%llu\n",
sp->f_files, sp->f_ffree, sp->f_favail);
#else
printf ("\tblocks: tot:%lu free:%lu avail:%lu\n",
sp->f_blocks, sp->f_bfree, sp->f_bavail);
printf ("\tinodes: tot:%lu free:%lu avail:%lu\n",
sp->f_files, sp->f_ffree, sp->f_favail);
#endif
}
}
free ((char *) mntbufp);
return 0;
}
#endif /* _lib_getvfsstat */
#if _lib_getmnt
/*
* di_getDiskEntries
*
* ULTRIX does this with a system call. The system call allows one
* to retrieve the information in a series of calls, but coding that
* looks a little tricky; I just allocate a huge buffer and do it in
* one shot.
*
* [mogul@wrl.dec.com (Jeffrey Mogul)]
*/
int
# if _proto_stdc
di_getDiskEntries (diDiskInfo_t **diskInfo, int *diCount)
# else
di_getDiskEntries (diskInfo, diCount)
diDiskInfo_t **diskInfo;
int *diCount;
# endif
{
diDiskInfo_t *diptr;
int count;
int bufsize;
int idx;
short fstype;
struct fs_data *fsdbuf;
int start;
int len;
if (di_lib_debug > 0) { printf ("# lib:getDiskEntries: getmnt\n"); }
bufsize = NMOUNT * sizeof (struct fs_data); /* enough for max # mounts */
fsdbuf = (struct fs_data *) malloc (bufsize);
if (fsdbuf == (struct fs_data *) NULL)
{
fprintf (stderr, "malloc (%d) for getmnt () failed errno %d\n",
bufsize, errno);
return -1;
}
start = 0;
count = getmnt (&start, fsdbuf, bufsize, STAT_MANY, 0);
if (count < 1)
{
fprintf (stderr, "Unable to do getmnt () [= %d] errno %d\n",
count, errno);
free ((char *) fsdbuf);
return -1;
}
*diCount = count;
*diskInfo = (diDiskInfo_t *) malloc (sizeof (diDiskInfo_t) * count);
if (*diskInfo == (diDiskInfo_t *) NULL)
{
fprintf (stderr, "malloc failed for diskInfo. errno %d\n", errno);
free ((char *) fsdbuf);
return -1;
}
memset ((char *) *diskInfo, '\0', sizeof (diDiskInfo_t) * count);
for (idx = 0; idx < count; idx++)
{
diptr = *diskInfo + idx;
diptr->printFlag = DI_PRNT_OK;
diptr->isLocal = TRUE;
diptr->isReadOnly = FALSE;
if ((fsdbuf [idx].fd_req.flags & MNT_LOCAL) != MNT_LOCAL)
{
diptr->isLocal = FALSE;
}
strncpy (diptr->special, fsdbuf [idx].fd_devname, DI_SPEC_NAME_LEN);
strncpy (diptr->name, fsdbuf [idx].fd_path, DI_NAME_LEN);
/* ULTRIX keeps these fields in units of 1K byte */
diptr->totalBlocks = fsdbuf [idx].fd_btot;
diptr->freeBlocks = fsdbuf [idx].fd_bfree;
diptr->availBlocks = (int) fsdbuf [idx].fd_bfreen;
diptr->totalInodes = fsdbuf [idx].fd_gtot;
diptr->freeInodes = fsdbuf [idx].fd_gfree;
diptr->availInodes = fsdbuf [idx].fd_gfree;
fstype = fsdbuf [idx].fd_fstype;
if (fstype == GT_UNKWN)
{
diptr->printFlag = DI_PRNT_IGNORE;
if (di_lib_debug > 2)
{
printf ("mnt: ignore: disk type unknown: %s\n",
diptr->name);
}
}
else if ((fstype > 0) && (fstype < GT_NUMTYPES))
{
strncpy (diptr->fsType, gt_names [fstype], DI_TYPE_LEN);
}
else
{
Snprintf (SPF(diptr->fsType, sizeof (diptr->fsType),
"Unknown fstyp %.2d"), fstype);
}
if ((fsdbuf [idx].fd_req.flags & MNT_RDONLY) == MNT_RDONLY)
{
diptr->isReadOnly = TRUE;
}
else
{
diptr->isReadOnly = FALSE;
}
convertMountOptions ((long) fsdbuf [idx].fd_req.flags, diptr);
trimChar (diptr->options, ',');
if (di_lib_debug > 1)
{
printf ("%s: %s\n", diptr->name, diptr->fsType);
printf ("\tblocks: tot:%ld free:%ld avail:%ld\n",
fsdbuf [idx].fd_btot, fsdbuf [idx].fd_bfree,
(int) fsdbuf [idx].fd_bfreen);
printf ("\tinodes: tot:%ld free:%ld\n",
fsdbuf [idx].fd_gtot, fsdbuf [idx].fd_gfree);
}
}
free ((char *) fsdbuf);
return 0;
}
#endif /* _lib_getmnt */
#if _lib_mntctl
/*
* di_getDiskEntries
*
* AIX uses mntctl to find out about mounted file systems
* This seems to be better than set/get/end, as we get the
* remote filesystem flag.
*
*/
# define DI_FSMAGIC 10 /* base AIX configuration has 5 file systems */
# define NUM_AIX_FSTYPES 6
static char *AIX_fsType [NUM_AIX_FSTYPES] =
{ "oaix", "", "nfs", "jfs", "", "cdrom" };
/*
* from xfsm-1.80:
*
* MNT_AIX - "aix"
* MNT_NFS - "nfs"
* MNT_JFS - "jfs"
* MNT_CDROM - "cdrom"
* other - "user defined"
*
*/
#define DI_RETRY_COUNT 5
int
# if _proto_stdc
di_getDiskEntries (diDiskInfo_t **diskInfo, int *diCount)
# else
di_getDiskEntries (diskInfo, diCount)
diDiskInfo_t **diskInfo;
int *diCount;
# endif
{
diDiskInfo_t *diptr;
int num; /* number of vmount structs returned */
char *vmbuf; /* buffer for vmount structs returned */
int vmbufsz; /* size in bytes of vmbuf */
int i; /* index for looping and stuff */
char *bufp; /* pointer into vmbuf */
struct vmount *vmtp; /* pointer into vmbuf */
struct vfs_ent *ve; /* pointer for file system type entry */
int len;
if (di_lib_debug > 0) { printf ("# lib:getDiskEntries: mntctl\n"); }
i = 0;
vmbufsz = sizeof (struct vmount) * DI_FSMAGIC; /* initial vmount buffer */
do
{
if ((vmbuf = (char *) malloc (vmbufsz)) == (char *) NULL)
{
fprintf (stderr, "malloc (%d) for mntctl() failed errno %d\n",
vmbufsz, errno);
return -1;
}
num = mntctl (MCTL_QUERY, vmbufsz, vmbuf);
/*
* vmbuf is too small, could happen for
* following reasons:
* - inital buffer is too small
* - newly mounted file system
*/
if (num == 0)
{
memcpy (&vmbufsz, vmbuf, sizeof (vmbufsz)); /* see mntctl(2) */
if (di_lib_debug > 0)
{
printf ("vmbufsz too small, new size: %d\n", vmbufsz);
}
free ((char *) vmbuf); /* free this last, it's still being used! */
++i;
}
} while (num == 0 && i < DI_RETRY_COUNT);
if (i >= DI_RETRY_COUNT)
{
free ((char *) vmbuf);
fprintf (stderr, "unable to allocate adequate buffer for mntctl\n");
return -1;
}
if (num == -1)
{
free ((char *) vmbuf);
fprintf (stderr,"%s errno %d\n", strerror (errno), errno);
return -1;
}
/* <num> vmount structs returned in vmbuf */
*diCount = num;
*diskInfo = (diDiskInfo_t *) calloc (sizeof (diDiskInfo_t), *diCount);
if (*diskInfo == (diDiskInfo_t *) NULL)
{
fprintf (stderr, "malloc failed for diskInfo. %s errno %d\n",
strerror (errno), errno);
return -1;
}
bufp = vmbuf;
for (i = 0; i < num; i++)
{
diptr = *diskInfo + i;
vmtp = (struct vmount *) bufp;
diptr->printFlag = DI_PRNT_OK;
diptr->isLocal = TRUE;
diptr->isReadOnly = FALSE;
if ((vmtp->vmt_flags & MNT_REMOTE) == MNT_REMOTE)
{
diptr->isLocal = FALSE;
}
if ((vmtp->vmt_flags & MNT_RDONLY) == MNT_RDONLY)
{
diptr->isReadOnly = TRUE;
}
*diptr->special = '\0';
if (diptr->isLocal == FALSE)
{
strncpy (diptr->special,
(char *) vmt2dataptr (vmtp, VMT_HOSTNAME),
DI_SPEC_NAME_LEN);
strncat (diptr->special, ":",
DI_SPEC_NAME_LEN - strlen (diptr->special) - 1);
}
strncat (diptr->special,
(char *) vmt2dataptr (vmtp, VMT_OBJECT),
DI_SPEC_NAME_LEN - strlen (diptr->special) - 1);
strncpy (diptr->name,
(char *) vmt2dataptr (vmtp, VMT_STUB), DI_NAME_LEN);
ve = getvfsbytype (vmtp->vmt_gfstype);
if (ve == (struct vfs_ent *) NULL || *ve->vfsent_name == '\0')
{
if (vmtp->vmt_gfstype >= 0 &&
(vmtp->vmt_gfstype < NUM_AIX_FSTYPES))
{
strncpy (diptr->fsType,
AIX_fsType [vmtp->vmt_gfstype], DI_TYPE_LEN);
}
}
else
{
strncpy (diptr->fsType, ve->vfsent_name, DI_TYPE_LEN);
}
strncpy (diptr->options, (char *) vmt2dataptr (vmtp, VMT_ARGS),
DI_OPT_LEN);
trimChar (diptr->options, ',');
strncpy (diptr->mountTime, ctime ((time_t *) &vmtp->vmt_time),
DI_MNT_TIME_LEN);
bufp += vmtp->vmt_length;
if (di_lib_debug > 0)
{
printf ("mnt:%s - %s : %s\n", diptr->name,
diptr->special, diptr->fsType);
printf ("\t%s\n", (char *) vmt2dataptr (vmtp, VMT_ARGS));
}
}
}
#endif /* _lib_mntctl */
#if (_statfs_2arg || \
_statfs_3arg) && \
! defined (_lib_statvfs) && \
! defined (_lib_getmntinfo) && \
! defined (_lib_getmnt) && \
! defined (_lib_GetDiskFreeSpace) && \
! defined (_lib_GetDiskFreeSpaceEx)
/*
* di_getDiskInfo
*
* SunOS/BSD/Pyramid/Some Linux
*
*/
# define DI_GETDISKINFO_DEF 1
void
# if _proto_stdc
di_getDiskInfo (diDiskInfo_t **diskInfo, int *diCount)
# else
di_getDiskInfo (diskInfo, diCount)
diDiskInfo_t **diskInfo;
int *diCount;
# endif
{
diDiskInfo_t *diptr;
int i;
struct statfs statBuf;
if (di_lib_debug > 0) { printf ("# lib:getDiskEntries: bsd-statfs 2/3arg\n"); }
for (i = 0; i < *diCount; ++i)
{
diptr = *diskInfo + i;
if (diptr->printFlag == DI_PRNT_OK)
{
if (statfs (diptr->name, &statBuf) == 0)
{
diptr->blockSize = (_fs_size_t) statBuf.f_bsize;
diptr->totalBlocks = (_fs_size_t) statBuf.f_blocks;
diptr->freeBlocks = (_fs_size_t) statBuf.f_bfree;
diptr->availBlocks = (_fs_size_t) statBuf.f_bavail;
diptr->totalInodes = statBuf.f_files;
diptr->freeInodes = statBuf.f_ffree;
diptr->availInodes = statBuf.f_ffree;
# if _lib_sysfs
sysfs (GETFSTYP, statBuf.f_fstyp, diptr->fsType);
# endif
if (di_lib_debug > 1)
{
printf ("%s: %s\n", diptr->name, diptr->fsType);
printf ("\tbsize:%ld\n", statBuf.f_bsize);
printf ("\tblocks: tot:%ld free:%ld avail:%ld\n",
statBuf.f_blocks, statBuf.f_bfree, statBuf.f_bavail);
printf ("\tinodes: tot:%ld free:%ld\n",
statBuf.f_files, statBuf.f_ffree);
}
} /* if we got the info */
else
{
fprintf (stderr, "statfs: %s ", diptr->name);
perror ("");
}
}
} /* for each entry */
}
#endif /* _statfs_2arg */
#if _lib_GetDiskFreeSpace && \
_lib_GetDriveType && \
_lib_GetLogicalDriveStrings
/*
* di_getDiskInfo
*
* Windows
*
*/
# define MSDOS_BUFFER_SIZE 256
# define BYTES_PER_LOGICAL_DRIVE 4
int
# if _proto_stdc
di_getDiskEntries (diDiskInfo_t **diskInfo, int *diCount)
# else
di_getDiskEntries (diskInfo, diCount)
diDiskInfo_t **diskInfo;
int *diCount;
# endif
{
diDiskInfo_t *diptr;
int i;
int diskflag;
int rc;
char *p;
char buff [MSDOS_BUFFER_SIZE];
# if _lib_GetDiskFreeSpaceEx
if (di_lib_debug > 0) { printf ("# lib:getDiskEntries: GetDiskFreeSpaceEx\n"); }
# else
# if _lib_GetDiskFreeSpace
if (di_lib_debug > 0) { printf ("# lib:getDiskEntries: GetDiskFreeSpace\n"); }
# endif
# endif
diskflag = DI_PRNT_IGNORE;
rc = GetLogicalDriveStrings (MSDOS_BUFFER_SIZE, buff);
*diCount = rc / BYTES_PER_LOGICAL_DRIVE;
*diskInfo = (diDiskInfo_t *) calloc (sizeof (diDiskInfo_t), *diCount);
if (*diskInfo == (diDiskInfo_t *) NULL)
{
fprintf (stderr, "malloc failed for diskInfo. errno %d\n", errno);
return -1;
}
for (i = 0; i < *diCount; ++i)
{
diptr = *diskInfo + i;
p = buff + (BYTES_PER_LOGICAL_DRIVE * i);
strncpy (diptr->name, p, DI_NAME_LEN);
rc = GetDriveType (p);
diptr->printFlag = DI_PRNT_OK;
if (rc == DRIVE_NO_ROOT_DIR)
{
diptr->printFlag = DI_PRNT_BAD;
}
/* assume that any removable drives before the */
/* first non-removable disk are floppies... */
else if (rc == DRIVE_REMOVABLE)
{
diptr->printFlag = diskflag;
}
else
{
diskflag = DI_PRNT_OK;
}
if (rc != DRIVE_REMOTE)
{
diptr->isLocal = TRUE;
}
} /* for each mounted drive */
return *diCount;
}
#endif /* _lib_GetDiskFreeSpace || _lib_GetDiskFreeSpaceEx */
#if _lib_GetVolumeInformation
/*
* di_getDiskInfo
*
* Windows
*
*/
# define DI_GETDISKINFO_DEF 1
void
# if _proto_stdc
di_getDiskInfo (diDiskInfo_t **diskInfo, int *diCount)
# else
di_getDiskInfo (diskInfo, diCount)
diDiskInfo_t **diskInfo;
int *diCount;
# endif
{
diDiskInfo_t *diptr;
int i;
int rc;
char volName [MSDOS_BUFFER_SIZE];
char fsName [MSDOS_BUFFER_SIZE];
DWORD serialNo;
DWORD maxCompLen;
DWORD fsFlags;
if (di_lib_debug > 0) { printf ("# lib:getDiskInfo: GetVolumeInformation\n"); }
for (i = 0; i < *diCount; ++i)
{
diptr = *diskInfo + i;
if (diptr->printFlag == DI_PRNT_OK)
{
rc = GetVolumeInformation (diptr->name,
volName, MSDOS_BUFFER_SIZE, &serialNo, &maxCompLen,
&fsFlags, fsName, MSDOS_BUFFER_SIZE);
strncpy (diptr->fsType, fsName, DI_TYPE_LEN);
strncpy (diptr->special, volName, DI_SPEC_NAME_LEN);
# if _lib_GetDiskFreeSpaceEx
{
ULONGLONG bytesAvail;
ULONGLONG bytesTotal;
ULONGLONG bytesFree;
rc = GetDiskFreeSpaceEx (diptr->name,
(PULARGE_INTEGER) &bytesAvail,
(PULARGE_INTEGER) &bytesTotal,
(PULARGE_INTEGER) &bytesFree);
if (rc > 0)
{
diptr->blockSize = (_fs_size_t) 1;
diptr->totalBlocks = (_fs_size_t) bytesTotal;
diptr->freeBlocks = (_fs_size_t) bytesFree;
diptr->availBlocks = (_fs_size_t) bytesAvail;
diptr->totalInodes = 0;
diptr->freeInodes = 0;
diptr->availInodes = 0;
}
else
{
diptr->printFlag = DI_PRNT_BAD;
if (di_lib_debug)
{
printf ("disk %s; could not get disk space\n",
diptr->name);
}
}
if (di_lib_debug > 1)
{
printf ("%s: %s\n", diptr->name, diptr->fsType);
printf ("\ttot:%llu free:%llu\n",
bytesTotal, bytesFree);
printf ("\tavail:%llu\n", bytesAvail);
}
}
# else
# if _lib_GetDiskFreeSpace
{
unsigned long sectorspercluster;
unsigned long bytespersector;
unsigned long totalclusters;
unsigned long freeclusters;
rc = GetDiskFreeSpace (diptr->name,
(LPDWORD) §orspercluster,
(LPDWORD) &bytespersector,
(LPDWORD) &freeclusters,
(LPDWORD) &totalclusters);
if (rc > 0)
{
diptr->blockSize = (_fs_size_t) (sectorspercluster *
bytespersector);
diptr->totalBlocks = (_fs_size_t) totalclusters;
diptr->freeBlocks = (_fs_size_t) freeclusters;
diptr->availBlocks = (_fs_size_t) freeclusters;
diptr->totalInodes = 0;
diptr->freeInodes = 0;
diptr->availInodes = 0;
}
else
{
diptr->printFlag = DI_PRNT_BAD;
if (di_lib_debug)
{
printf ("disk %s; could not get disk space\n",
diptr->name);
}
}
if (di_lib_debug > 1)
{
printf ("%s: %s\n", diptr->name, diptr->fsType);
printf ("\ts/c:%ld b/s:%ld\n", sectorspercluster,
bytespersector);
printf ("\tclusters: tot:%ld free:%ld\n",
totalclusters, freeclusters);
}
}
# endif
# endif
} /* if printable drive */
} /* for each mounted drive */
}
#endif /* _lib_GetVolumeInformation */
/*
* Realloc
*
* portable realloc
*
*/
void *
#if _proto_stdc
Realloc (void *ptr, Size_t size)
#else
Realloc (ptr, size)
void *ptr;
Size_t size;
#endif
{
if (ptr == (void *) NULL)
{
ptr = (void *) malloc (size);
}
else
{
ptr = (void *) realloc (ptr, size);
}
return ptr;
}
static void
#if _proto_stdc
convertMountOptions (long flags, diDiskInfo_t *diptr)
#else
convertMountOptions (flags, diptr)
long flags;
diDiskInfo_t *diptr;
#endif
{
#if defined (MNT_RDONLY)
if ((flags & MNT_RDONLY) == MNT_RDONLY)
{
strncat (diptr->options, "ro,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
else
{
strncat (diptr->options, "rw,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (MNT_FORCE)
if ((flags & MNT_FORCE) == MNT_FORCE)
{
strncat (diptr->options, "force,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (MNT_GRPID)
if ((flags & MNT_GRPID) == MNT_GRPID)
{
strncat (diptr->options, "grpid,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (MNT_MAGICLINKS)
if ((flags & MNT_MAGICLINKS) == MNT_MAGICLINKS)
{
strncat (diptr->options, "magiclinks,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (MNT_MLSD)
if ((flags & MNT_MLSD) == MNT_MLSD)
{
strncat (diptr->options, "mlsd,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (MNT_NOATIMES)
if ((flags & MNT_NOATIMES) == MNT_NOATIMES)
{
strncat (diptr->options, "noatime,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (MNT_NOCACHE)
if ((flags & MNT_NOCACHE) == MNT_NOCACHE)
{
strncat (diptr->options, "nocache,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (MNT_NOCOREDUMP)
if ((flags & MNT_NOCOREDUMP) == MNT_NOCOREDUMP)
{
strncat (diptr->options, "nocoredump,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (MNT_NODEV)
if ((flags & MNT_NODEV) == MNT_NODEV)
{
strncat (diptr->options, "nodev,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (MNT_NODEVMTIME)
if ((flags & MNT_NODEVMTIME) == MNT_NODEVMTIME)
{
strncat (diptr->options, "nodevmtime,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (MNT_NOEXEC)
if ((flags & MNT_NOEXEC) == MNT_NOEXEC)
{
strncat (diptr->options, "noexec,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (MNT_NOSUID)
if ((flags & MNT_NOSUID) == MNT_NOSUID)
{
strncat (diptr->options, "nosuid,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (MNT_QUOTA)
if ((flags & MNT_QUOTA) == MNT_QUOTA)
{
strncat (diptr->options, "quota,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (MNT_SECURE)
if ((flags & MNT_SECURE) == MNT_SECURE)
{
strncat (diptr->options, "secure,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (MNT_SMSYNC2)
if ((flags & MNT_SMSYNC2) == MNT_SMSYNC2)
{
strncat (diptr->options, "smsync2,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (MNT_SOFTDEP)
if ((flags & MNT_SOFTDEP) == MNT_SOFTDEP)
{
strncat (diptr->options, "softdep,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (MNT_SYMPERM)
if ((flags & MNT_SYMPERM) == MNT_SYMPERM)
{
strncat (diptr->options, "symperm,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (MNT_SYNC)
if ((flags & MNT_SYNC) == MNT_SYNC)
{
strncat (diptr->options, "sync,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (MNT_SYNCHRONOUS)
if ((flags & MNT_SYNCHRONOUS) == MNT_SYNCHRONOUS)
{
strncat (diptr->options, "sync,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (MNT_THROTTLE)
if ((flags & MNT_THROTTLE) == MNT_THROTTLE)
{
strncat (diptr->options, "throttle,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (MNT_UNION)
if ((flags & MNT_UNION) == MNT_UNION)
{
strncat (diptr->options, "union,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (MNT_UNION)
if ((flags & MNT_UNION) == MNT_UNION)
{
strncat (diptr->options, "union,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
}
static void
#if _proto_stdc
convertNFSMountOptions (long flags, long wsize, long rsize, diDiskInfo_t *diptr)
#else
convertNFSMountOptions (flags, wsize, rsize, diptr)
long flags;
long wsize;
long rsize;
diDiskInfo_t *diptr;
#endif
{
#if defined (NFSMNT_SOFT)
if ((flags & NFSMNT_SOFT) != NFSMNT_SOFT)
{
strncat (diptr->options, "hard,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (NFSMNT_WSIZE)
if ((flags & NFSMNT_WSIZE) == NFSMNT_WSIZE)
{
char tmp [64];
Snprintf (SPF(tmp, sizeof (tmp), "wsize=%ld,"), wsize);
strncat (diptr->options, tmp,
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (NFSMNT_RSIZE)
if ((flags & NFSMNT_RSIZE) == NFSMNT_RSIZE)
{
char tmp [64];
Snprintf (SPF(tmp, sizeof (tmp), "rsize=%ld,"), rsize);
strncat (diptr->options, tmp,
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (NFSMNT_INT) && defined (NFSMNT_SOFT)
if ((flags & NFSMNT_SOFT) != NFSMNT_SOFT &&
(flags & NFSMNT_INT) == NFSMNT_INT)
{
strncat (diptr->options, "intr,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
#if defined (NFSMNT_TCP)
if ((flags & NFSMNT_TCP) != NFSMNT_TCP)
{
strncat (diptr->options, "udp,",
DI_OPT_LEN - strlen (diptr->options) - 1);
}
#endif
}
static void
#if _proto_stdc
trimChar (char *str, int ch)
#else
trimChar (str, ch)
char *str;
int ch;
#endif
{
int len;
len = strlen (str);
if (len > 0)
{
--len;
}
if (len >= 0)
{
if (str [len] == ch)
{
str [len] = '\0';
}
}
}
#if ! defined (DI_GETDISKINFO_DEF)
void
# if _proto_stdc
di_getDiskInfo (diDiskInfo_t **diskInfo, int *diCount)
# else
di_getDiskInfo (diskInfo, diCount)
diDiskInfo_t **diskInfo;
int *diCount;
# endif
{
if (di_lib_debug > 0) { printf ("# lib:getDiskInfo: empty\n"); }
return;
}
#endif
void
# if _proto_stdc
di_testRemoteDisk (diDiskInfo_t *diskInfo)
# else
di_testRemoteDisk (diskInfo)
diDiskInfo_t *diskInfo;
# endif
{
if (strcmp (diskInfo->fsType, "nfs") == 0 ||
strcmp (diskInfo->fsType, "nfs3") == 0)
{
diskInfo->isLocal = FALSE;
}
}
syntax highlighted by Code2HTML, v. 0.9.1