/* $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 #if _hdr_ctype # include #endif #if _hdr_errno # include #endif #if _hdr_stdlib # include #endif #if _sys_types # include #endif #if _hdr_string # include #endif #if _hdr_strings && ((! defined (_hdr_string)) || (_include_string)) # include #endif #if _hdr_memory # include #endif #if _include_malloc && _hdr_malloc # include #endif #if _hdr_unistd # include #endif #if _hdr_time # include #endif #if _sys_time # include #endif #if _sys_stat # include #endif #if _sys_param # include #endif #if _sys_mnttab # include #endif #if _hdr_mnttab # include #endif #if _hdr_mntent # include #endif #if _sys_mntent # include #endif #if _sys_mount # include #endif #if _sys_fstypes # include #endif #if _sys_fs_types # include #endif #if _sys_mntctl # include #endif #if _sys_vmount # include #endif #if _sys_statfs && ! defined (_sys_statvfs) # include #endif #if _hdr_fshelp # include #endif #if _sys_statvfs # include #endif #if _sys_fstyp # include # define DI_TYPE_LEN FSTYPSZ #endif #if _sys_vfs # include #endif #if _sys_vfstab # include # if ! defined (DI_TYPE_LEN) # define DI_TYPE_LEN FSTYPSZ # endif #endif #if _hdr_windows # include /* windows */ #endif #if _hdr_kernel_fs_info # include #endif #if _hdr_storage_Directory # include #endif #if _hdr_storage_Entry # include #endif #if _hdr_storage_Path # include #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; } /* 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; } }