]> git.pld-linux.org Git - packages/di.git/blob - di-distr.002
- updated to 4.3
[packages/di.git] / di-distr.002
1 #! /bin/sh
2 # This is a shell archive.  Remove anything before this line, then unpack
3 # it by saving it into a file and typing "sh file".  To overwrite existing
4 # files, type "sh file -c".  You can also feed this as standard input via
5 # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
6 # will see the following message at the end:
7 #               "End of archive 2 (of 3)."
8 # Contents:  di.c
9 # Wrapped by root@seer on Thu Feb 24 10:15:51 2000
10 PATH=/bin:/usr/bin:/usr/ucb ; export PATH
11 if test -f 'di.c' -a "${1}" != "-c" ; then
12   echo shar: Will not clobber existing file \"'di.c'\"
13 else
14 echo shar: Extracting \"'di.c'\" \(97566 characters\)
15 sed "s/^X//" >'di.c' <<'END_OF_FILE'
16 X#ifndef lint
17 Xstatic char    di_c_sccsid [] =
18 X"@(#)di.c      1.21";
19 Xstatic char    di_c_rcsid [] =
20 X"$Id$";
21 Xstatic char    di_c_source [] =
22 X"$Source$";
23 Xstatic char    copyright [] =
24 X"Copyright 1994-1999 Brad Lanam, Walnut Creek, CA";
25 X#endif
26 X
27 X/*
28 X * di.c
29 X *
30 X *   Copyright 1994-1999 Brad Lanam,  Walnut Creek, CA
31 X *
32 X *  Warning: Do not replace your systems 'df' command with this program.
33 X *           You will in all likelihood break your installation procedures.
34 X *
35 X *  Usage: di -AafntwWx [file [...]]
36 X *            -A   : print all fields (used for debugging)
37 X *            -a   : print all mounted devices; normally, those
38 X *                   with 0 total blocks are not printed.  e.g.
39 X *                   /dev/proc, /dev/fd.
40 X *            -d x : size to print blocks in (p, k, m, g, <n>)
41 X *            -f x : use format string <x>
42 X *            -i x : ignore filesystem type(s) x, where x is a comma
43 X *                   separated list.
44 X *            -I x : include only filesystem type(s) x, where x is a
45 X *                   separated list.
46 X *            -l   : local filesystems only
47 X *            -n   : don't print header
48 X *            -s t : sort type
49 X *            -t   : print totals
50 X *            -w n : use <n> for the block print width (default 8).
51 X *            -W n : use <n> for the inode print width (default 7).
52 X *            -x n : debug level <n>
53 X *
54 X *  All values are reported in K (1024 bytes).
55 X *
56 X *  Sort types (by name is default):
57 X *      n - none (mount order)
58 X *      s - special
59 X *      r - reverse sort
60 X *
61 X *  Format string values:
62 X *      m - mount point
63 X *      M - mount point, full length
64 X *      b - total kbytes
65 X *      B - total kbytes available for use by the user.
66 X *             [ (tot - (free - avail) ]
67 X *      u - kbytes used (actual number of kbytes used) [ (tot - free) ]
68 X *      c - calculated number of kbytes used [ (tot - avail) ]
69 X *      f - kbytes free
70 X *      v - kbytes available
71 X *      p - percentage not available for use.
72 X *          (number of blocks not available for use / total disk space)
73 X *             [ (tot - avail) / tot ]
74 X *      1 - percentage used.
75 X *          (actual number of blocks used / total disk space)
76 X *             [ (tot - free) / tot ]
77 X *      2 - percentage of user-available space in use (bsd style).
78 X *          Note that values over 100% are possible.
79 X *          (actual number of blocks used / disk space available to user)
80 X *             [ (tot - free) / (tot - (free - avail)) ]
81 X *      i - total i-nodes (files)
82 X *      U - used i-nodes
83 X *      F - free i-nodes
84 X *      P - percent i-nodes used     [ (tot - avail) / tot ]
85 X *      s - filesystem name (special)
86 X *      S - filesystem name (special), full length
87 X *      t - disk partition type
88 X *      T - disk partition type (full length)
89 X *      I - mount time
90 X *      O - mount options.
91 X *
92 X *  System V.4 `/usr/bin/df -v` Has format: msbuf1 (w/-d512 option: 512 byte blocks)
93 X *  System V.4 `/usr/bin/df -k` Has format: sbcvpm
94 X *  System V.4 `/usr/ucb/df`    Has format: sbuv2m
95 X *
96 X *  The default format string for this program is: smbuvpT
97 X *
98 X *  The environment variable "DIFMT" may be set to the desired format
99 X *  string.
100 X *
101 X *  Note that for filesystems that do not have (S512K fs) or systems (SysV.3)
102 X *  that do not report available blocks, the number of available blocks is
103 X *  equal to the number of free blocks.
104 X *
105 X *  HISTORY:
106 X *     24 feb 2000 bll
107 X *          Updated for BeOS.  This required changes to support c++
108 X *          compilation (ansi style functions).  Fixes for linux.
109 X *     17 dec 99 bll
110 X *          Added sys/fs_types.h (Digital Unix (tru64)).
111 X *     3 jan 99 bll
112 X *          Finalize changes for metaconfig.
113 X *          Always get stat() for disk device.
114 X *          Remove duplicate disks from display.
115 X *          Add NetBSD, Unicos, IRIX changes
116 X *     8 sep 97 bll
117 X *          Solaris large file version; AIX typo fix
118 X *     15 aug 95 bll
119 X *          Ignore will check the file system type beforehand if possible.
120 X *          Fixed local mount stuff for osf1.
121 X *     9 aug 95 bll
122 X *          Changed totals to use double; the totals can now be displayed with
123 X *          any wanted block size; sizes > one k have a single decimal point.
124 X *          -d option specifies block size.
125 X *          -l option for local file systems only.
126 X *     7 aug 95 bll
127 X *          convex fix.
128 X *     29 jul 95 bll
129 X *          Fixed bsdi variants.  The fragment size wasn't being supported.
130 X *     22 jul 95 bll
131 X *          fix problem with display widths in conjunction with ignore/include
132 X *     20 feb 95 bll
133 X *          added ignore/include file system type lists.
134 X *     8 jan 95 bll
135 X *          Added FreeBsd 2.x
136 X *     6 dec 94 bll
137 X *          sco nfs 'nothing' fix.
138 X *     28 nov 94 bll
139 X *          bsdi [bag@clipper.cs.kiev.ua (Andrey Blochintsev)]
140 X *     24 nov 94 bll
141 X *          Added FreeBsd - like OSF/1, but w/o nice mount name table.
142 X *     1 may 94 bll
143 X *          removed ill conceived mount options stuff.  Added AIX
144 X *          (Erik O'Shaughnessy eriko@risc.austin.ibm.com).
145 X *          Added coherent.
146 X *     9 apr 94 bll
147 X *          T format from Bill Davidsen. SunOS file system type.
148 X *          mount options.
149 X *     7 apr 94 bll
150 X *          cdrom under solaris returning -1 in addition to -2.
151 X *          Changed the test to test for any negative value.
152 X *    5 apr 94 pm
153 X *         Filesystem type info, and whether its read-write, readonly
154 X *         etc is in the mntent structure.  Added code to support it.
155 X *                  [Pat Myrto <pat@rwing.uucp>]
156 X *    25 mar 94 bll
157 X *          sun had f_bfree instead of f_bavail!
158 X *          Xenix, linux.
159 X *          -w, -W options, -B option, fixed width for -f M, -f S.
160 X *          Usage.  Allow other characters in format string.
161 X *     4 mar 94 bll
162 X *          -f B, bug fixes. bcopy.
163 X *          Solaris cdrom reports total, not free or avail.
164 X *          Allow command line specification of file names.
165 X *     3 mar 94 bll
166 X *          support for OSF/1 and ULTRIX, -F, -f M, -f S
167 X *                  [mogul@wrl.dec.com (Jeffrey Mogul)]
168 X *     3 mar 94   bll
169 X *          Allow command line specification of filename (s).
170 X *          Sort output.  Test of nonexistent return code removed.
171 X *     1 mar 94   bll
172 X *          # of inodes can be -1L if unreportable.
173 X *                  [jjb@jagware.bcc.com (J.J.Bailey)]
174 X *                  [Mark Neale <mark@edscom.demon.co.uk>]
175 X *          getDiskInfo () returning garbage
176 X *                  [costales@ICSI.Berkeley.EDU (Bryan Costales)]
177 X *                  [Mark Neale <mark@edscom.demon.co.uk>]
178 X *          pyramid #ifdefs
179 X *                  [vogelke@c-17igp.wpafb.af.mil (Contr Karl Vogel)]
180 X *          name must be maxpathlen
181 X *                  [Mark Neale <mark@edscom.demon.co.uk>]
182 X *          error prints/compile warnings.
183 X *                  [Mark Neale <mark@edscom.demon.co.uk>]
184 X *
185 X */
186 X
187 X#include "config.h"
188 X
189 X#include <stdio.h>
190 X#include <ctype.h>
191 X#include <errno.h>
192 X#if defined (I_STDLIB)
193 X# include <stdlib.h>
194 X#endif
195 X#if defined (I_SYS_TYPES)
196 X# include <sys/types.h>
197 X#endif
198 X#if defined (I_LIMITS)
199 X# include <limits.h>
200 X#endif
201 X#if defined (I_STRING)
202 X# include <string.h>
203 X#else
204 X# include <strings.h>
205 X#endif
206 X#if defined (I_MEMORY)
207 X# include <memory.h>
208 X#endif
209 X#if defined (I_MALLOC)
210 X# include <malloc.h>
211 X#endif
212 X#if defined (I_UNISTD)
213 X# include <unistd.h>
214 X#endif
215 X#if defined (I_TIME)
216 X# include <time.h>
217 X#endif
218 X#if defined (I_SYS_TIME)
219 X# include <sys/time.h>
220 X#endif
221 X#if defined (I_SYS_STAT)
222 X# include <sys/stat.h>
223 X#endif
224 X#if defined (I_SYS_PARAM)
225 X# include <sys/param.h>
226 X#endif
227 X
228 X#if defined (I_SYS_MNTTAB)
229 X# include <sys/mnttab.h>
230 X#endif
231 X#if defined (I_MNTTAB)
232 X# include <mnttab.h>
233 X#endif
234 X#if defined (I_MNTENT)
235 X# include <mntent.h>
236 X#endif
237 X#if defined (I_SYS_MNTENT)
238 X# include <sys/mntent.h>
239 X#endif
240 X#if defined (I_SYS_MOUNT)
241 X# include <sys/mount.h>
242 X#endif
243 X#if defined (I_SYS_FSTYPES)
244 X# include <sys/fstypes.h>
245 X#endif
246 X#if defined (I_SYS_FS_TYPES)
247 X# include <sys/fs_types.h>
248 X#endif
249 X#if defined (I_SYS_MNTCTL)
250 X# include <sys/mntctl.h>
251 X#endif
252 X#if defined (I_SYS_VMOUNT)
253 X# include <sys/vmount.h>
254 X#endif
255 X#if defined (I_SYS_STATFS) && ! defined (I_SYS_STATVFS)
256 X# include <sys/statfs.h>
257 X#endif
258 X#if defined (I_FSHELP)
259 X# include <fshelp.h>
260 X#endif
261 X#if defined (I_SYS_STATVFS)
262 X# include <sys/statvfs.h>
263 X#endif
264 X#if defined (I_SYS_FSTYP)
265 X# include <sys/fstyp.h>
266 X# define DI_TYPE_LEN          FSTYPSZ
267 X#endif
268 X#if defined (I_SYS_VFS)
269 X# include <sys/vfs.h>
270 X#endif
271 X#if defined (I_SYS_VFSTAB)
272 X# include <sys/vfstab.h>
273 X# if ! defined (DI_TYPE_LEN)
274 X#  define DI_TYPE_LEN         FSTYPSZ
275 X# endif
276 X#endif
277 X#if defined (I_FSHELP)
278 X# include <fshelp.h>
279 X#endif
280 X
281 X#if defined (I_WINDOWS)
282 X# include <windows.h>            /* windows */
283 X#endif
284 X#if defined (I_KERNFSINFO)
285 X# include <kernel/fs_info.h>
286 X#endif
287 X#if defined (I_STOR_DIRECTORY)
288 X# include <storage/Directory.h>
289 X#endif
290 X#if defined (I_STOR_ENTRY)
291 X# include <storage/Entry.h>
292 X#endif
293 X/*#if defined (I_STOR_NODE)
294 X# include <storage/Node.h>
295 X#endif  */
296 X#if defined (I_STOR_PATH)
297 X# include <storage/Path.h>
298 X#endif
299 X
300 X#if ! defined (HAS_MEMCPY) && ! defined (memcpy)
301 X# if ! defined (HAS_BCOPY)
302 X   error No memcpy/bcopy available.
303 X# else
304 X#  define memcpy(dst, src, cnt)     (bcopy((src), (dst), (cnt)), dst)
305 X# endif
306 X#endif
307 X
308 X#if ! defined (MAXPATHLEN)
309 X# if defined (_POSIX_PATH_MAX)
310 X#  define MAXPATHLEN        _POSIX_PATH_MAX
311 X# else
312 X#  if defined (PATH_MAX)
313 X#   define MAXPATHLEN        PATH_MAX
314 X#  endif
315 X#  if defined (LPNMAX)
316 X#   define MAXPATHLEN         LPNMAX
317 X#  endif
318 X# endif
319 X#endif
320 X
321 X#if ! defined (DI_TYPE_LEN)
322 X# define DI_TYPE_LEN          16
323 X#endif
324 X
325 X#define DI_FSMAGIC 5   /* base AIX configuration has 5 file systems */
326 X
327 X#if defined (HAS_STATFS_SYSV3) && ! defined (HAS_STATVFS) && \
328 X    ! defined (HAS_GETMNTINFO) && ! defined (HAS_GETMNT) /* SYSV.3 */
329 X# if defined (Ubsize) && Ubsize != ""
330 X#  define UBSIZE            Ubsize
331 X# endif
332 X# if ! defined (UBSIZE)
333 X#  define UBSIZE            512
334 X# endif
335 X#endif
336 X
337 X#if (defined (HAS_GETMNTENT) || defined (HAS_STATFS_BSD) || \
338 X        defined (HAS_STATFS_SYSV3)) && ! defined (HAS_GETMNTINFO) && \
339 X        ! defined (HAS_GETMNT)
340 X# if defined (MOUNTED)
341 X#  define DI_MOUNT_FILE        MOUNTED
342 X# else
343 X#  if defined (MNTTAB)
344 X#   define DI_MOUNT_FILE       MNTTAB
345 X#  else
346 X#   define DI_MOUNT_FILE       "/etc/mnttab"
347 X#  endif
348 X# endif
349 X#endif
350 X
351 X#if ! defined (HAS_MEMSET) && ! defined (memset)
352 X# if ! defined (HAS_BZERO)
353 X   error No memset/bzero available.
354 X# else
355 X#  define memset(s,c,n)    (bzero ((s), (n)), s)
356 X# endif
357 X#endif
358 X
359 X#if defined (NEED_GETENV_DEF)
360 X  extern char *getenv _((char *));
361 X#endif
362 X
363 X#if defined (NEED_STATFS_DEFS)
364 X  extern int statfs _((char *, struct statfs *));
365 X#endif
366 X
367 X#if defined (NEED_ERRNO_DEFS)
368 Xextern int     errno;
369 X#endif
370 X
371 X#if (defined (_LARGEFILE_SOURCE) || defined (_LARGEFILE64_SOURCE)) && \
372 X        _FILE_OFFSET_BITS == 64
373 X# define HAS_64BIT_STATFS_FLDS 1
374 X#endif
375 X
376 X#if defined (HAS_64BIT_STATFS_FLDS)
377 Xtypedef unsigned long long _fs_size_t;
378 Xtypedef long long _s_fs_size_t;
379 X#else
380 Xtypedef unsigned long _fs_size_t;
381 Xtypedef long _s_fs_size_t;
382 X#endif
383 X
384 X#if ! defined (HAS_OPTIND)
385 X  extern int optind;
386 X  extern char *optarg;
387 X#endif
388 X
389 X/* end of system specific includes/configurations */
390 X
391 X#if ! defined (TRUE)
392 X# define TRUE             1
393 X#endif
394 X#if ! defined (FALSE)
395 X# define FALSE            0
396 X#endif
397 X
398 X#define DI_F_ALL               0x00000001
399 X#define DI_F_LOCAL_ONLY        0x00000002
400 X#define DI_F_TOTAL             0x00000010
401 X#define DI_F_NO_HEADER         0x00000020
402 X#define DI_F_DEBUG_HDR         0x00000040
403 X
404 X    /* mount information */
405 X#define DI_FMT_MOUNT           'm'
406 X#define DI_FMT_MOUNT_FULL      'M'
407 X#define DI_FMT_SPECIAL         's'
408 X#define DI_FMT_SPECIAL_FULL    'S'
409 X#define DI_FMT_TYPE            't'
410 X#define DI_FMT_TYPE_FULL       'T'
411 X
412 X    /* disk information */
413 X#define DI_FMT_BTOT            'b'
414 X#define DI_FMT_BTOT_AVAIL      'B'
415 X#define DI_FMT_BUSED           'u'
416 X#define DI_FMT_BCUSED          'c'
417 X#define DI_FMT_BFREE           'f'
418 X#define DI_FMT_BAVAIL          'v'
419 X#define DI_FMT_BPERC_AVAIL     'p'
420 X#define DI_FMT_BPERC_FREE      '1'
421 X#define DI_FMT_BPERC_BSD       '2'
422 X#define DI_FMT_ITOT            'i'
423 X#define DI_FMT_IUSED           'U'
424 X#define DI_FMT_IFREE           'F'
425 X#define DI_FMT_IPERC           'P'
426 X#define DI_FMT_MOUNT_TIME      'I'
427 X#define DI_FMT_MOUNT_OPTIONS   'O'
428 X
429 X#define DI_IGNORE           0
430 X#define DI_OK               1
431 X#define DI_BAD              2
432 X
433 X#define DI_SORT_NONE        0
434 X#define DI_SORT_NAME        1
435 X#define DI_SORT_SPECIAL     2
436 X
437 X#define DI_SORT_ASCENDING   1
438 X#define DI_SORT_DESCENDING  -1
439 X
440 X#define DI_UNKNOWN_DEV      -1L
441 X#define DI_LIST_SEP         ","
442 X
443 X#define DI_ALL_FORMAT          "MTS\n\tIO\n\tbuf1\n\tbcvp\n\tBuv2\n\tiUFP"
444 X
445 X#define DI_HALF_K              512.0
446 X#define DI_ONE_K               1024.0
447 X#define DI_ONE_MEG             1048576.0
448 X#define DI_ONE_GIG             1073241824.0
449 X
450 X#if ! defined (MAXPATHLEN)
451 X# define MAXPATHLEN         255
452 X#endif
453 X#define DI_SPEC_NAME_LEN       MAXPATHLEN
454 X#define DI_OPT_LEN             MAXPATHLEN
455 X#define DI_MNT_TIME_LEN        24
456 X
457 X#define DI_RETRY_COUNT         5
458 X#define DI_MAX_REMOTE_TYPES    20
459 X
460 X   /* you may want to change some of these values.  Be sure to change all */
461 X   /* related entries.                                                    */
462 X/* #define DI_DEFAULT_FORMAT      "mbuvpiUFP" */
463 X#if ! defined (DI_DEFAULT_FORMAT)
464 X# define DI_DEFAULT_FORMAT      "smbuvpT"
465 X#endif
466 X#if defined (HAS_MNT_TIME)
467 X# define DI_DEF_MOUNT_FORMAT    "MSTIO"
468 X#else
469 X# define DI_DEF_MOUNT_FORMAT    "MSTO"
470 X#endif
471 X#define DI_PERC_FMT            "%3.0f%% "
472 X#define DI_PERC_LBL_FMT        "%5s"
473 X#define DI_NAME_LEN            MAXPATHLEN
474 X#define DI_FSTYPE_FMT          "%-7.7s"
475 X#define DI_MOUNT_FMT           "%-15.15s"
476 X#define DI_SPEC_FMT            "%-18.18s"
477 X
478 X#define DI_UNKNOWN_FSTYPE      "Unknown fstyp %.2d"
479 X
480 Xtypedef unsigned long _ulong;
481 Xtypedef int (*DI_SORT_FUNC) _((char *, char *));
482 X
483 Xtypedef struct
484 X{
485 X    double          totalBlocks;
486 X    double          freeBlocks;
487 X    double          availBlocks;
488 X    _fs_size_t      totalInodes;
489 X    _fs_size_t      freeInodes;
490 X    _fs_size_t      availInodes;
491 X    _ulong          st_dev;                      /* disk device number   */
492 X    _ulong          sp_dev;                      /* special device number*/
493 X    _ulong          sp_rdev;                     /* special rdev #       */
494 X    char            printFlag;                   /* do we want to print  */
495 X                                                 /* this entry?          */
496 X    char            isLocal;                     /* is this mount point  */
497 X                                                 /* local?               */
498 X    char            name [DI_NAME_LEN + 1];         /* mount point          */
499 X    char            special [DI_SPEC_NAME_LEN + 1]; /* special device name  */
500 X    char            fsType [DI_TYPE_LEN + 1];       /* type of file system  */
501 X    char            options [DI_OPT_LEN + 1];
502 X    char            mountTime [DI_MNT_TIME_LEN + 1];
503 X} DiskInfo;
504 X
505 Xstatic DiskInfo     *diskInfo = { (DiskInfo *) NULL };
506 Xstatic int          diCount = { 0 };
507 Xstatic int          debug = { 0 };
508 Xstatic _ulong       flags = { 0 };
509 Xstatic int          sortType = { DI_SORT_NAME };
510 Xstatic int          sortOrder = { DI_SORT_ASCENDING };
511 Xstatic char         *formatString = { DI_DEFAULT_FORMAT };
512 Xstatic char         mountFormat [20];
513 X static char         specialFormat [20];
514 Xstatic char         typeFormat [20];
515 Xstatic char         optFormat [20];
516 Xstatic char         mTimeFormat [20];
517 Xstatic int          width = { 8 };
518 Xstatic int          inodeWidth = { 7 };
519 Xstatic char         blockFormat [20];
520 Xstatic char         blockLabelFormat [20];
521 Xstatic char         inodeFormat [20];
522 Xstatic char         inodeLabelFormat [20];
523 Xstatic char         **ignoreList = { (char **) NULL };
524 Xstatic char         **includeList = { (char **) NULL };
525 Xstatic double       dispBlockSize = { DI_ONE_MEG };
526 Xstatic int          remoteFileSystemCount = { 0 };
527 Xstatic char         remoteFileSystemTypes [DI_MAX_REMOTE_TYPES][DI_TYPE_LEN];
528 X
529 X
530 Xstatic void cleanup             _((void));
531 Xstatic void printDiskInfo       _((void));
532 Xstatic void printInfo           _((DiskInfo *));
533 Xstatic void addTotals           _((DiskInfo *, DiskInfo *));
534 Xstatic void printTitle          _((void));
535 Xstatic void printPerc           _((double, double, char *));
536 Xstatic char *Realloc            _((char *, long));
537 Xstatic void sortArray           _((char *, int, int, DI_SORT_FUNC));
538 Xstatic int  diCompare           _((char *, char *));
539 Xstatic void getDiskStatInfo     _((void));
540 Xstatic void getDiskSpecialInfo  _((void));
541 Xstatic void printFileInfo       _((int, int, char *[]));
542 Xstatic void checkDiskInfo       _((void));
543 Xstatic void usage               _((void));
544 Xstatic void processArgs         _((int, char *[]));
545 Xstatic void parseList           _((char ***, char *));
546 Xstatic void checkIgnoreList     _((DiskInfo *));
547 Xstatic void checkIncludeList    _((DiskInfo *));
548 X
549 Xstatic int  getDiskEntries      _((void));
550 Xstatic void getDiskInfo         _((void));
551 X
552 Xint
553 X#if defined (CAN_PROTOTYPE)
554 Xmain (int argc, char *argv [])
555 X#else
556 Xmain (argc, argv)
557 X    int                 argc;
558 X    char                *argv [];
559 X#endif
560 X{
561 X    char                *ptr;
562 X
563 X
564 X    ptr = argv [0] + strlen (argv [0]) - 2;
565 X    if (memcmp (ptr, MPROG, 2) == 0)
566 X    {
567 X        formatString = DI_DEF_MOUNT_FORMAT;
568 X    }
569 X    else    /* don't use DIFMT env var if running mi. */
570 X    {
571 X        if ((ptr = getenv ("DIFMT")) != (char *) NULL)
572 X        {
573 X            formatString = ptr;
574 X        }
575 X    }
576 X
577 X    processArgs (argc, argv);
578 X    if (debug > 0)
579 X    {
580 X        printf ("di ver $Revision$\n");
581 X    }
582 X
583 X    if (getDiskEntries () < 0)
584 X    {
585 X        cleanup ();
586 X        exit (1);
587 X    }
588 X
589 X    getDiskInfo ();
590 X    getDiskSpecialInfo ();
591 X    checkDiskInfo ();
592 X    if (optind < argc)
593 X    {
594 X        getDiskStatInfo ();
595 X        printFileInfo (optind, argc, argv);
596 X    }
597 X    else
598 X    {
599 X        printDiskInfo ();
600 X    }
601 X
602 X    cleanup ();
603 X    exit (0);
604 X}
605 X
606 X/*
607 X * cleanup
608 X *
609 X * free up allocated memory
610 X *
611 X */
612 X
613 Xstatic void
614 X#if defined (CAN_PROTOTYPE)
615 Xcleanup (void)
616 X#else
617 Xcleanup ()
618 X#endif
619 X{
620 X    char        **lptr;
621 X
622 X
623 X    if (diskInfo != (DiskInfo *) NULL)
624 X    {
625 X        free ((char *) diskInfo);
626 X    }
627 X
628 X    if (ignoreList != (char **) NULL)
629 X    {
630 X        lptr = ignoreList;
631 X        while (*lptr != (char *) NULL)
632 X        {
633 X            free ((char *) *lptr);
634 X            ++lptr;
635 X        }
636 X        free ((char *) ignoreList);
637 X    }
638 X
639 X    if (includeList != (char **) NULL)
640 X    {
641 X        lptr = includeList;
642 X        while (*lptr != (char *) NULL)
643 X        {
644 X            free ((char *) *lptr);
645 X            ++lptr;
646 X        }
647 X        free ((char *) includeList);
648 X    }
649 X}
650 X
651 X/*
652 X * printDiskInfo
653 X *
654 X * Print out the disk information table.
655 X * Loops through all mounted disks, prints and calculates totals.
656 X *
657 X */
658 X
659 Xstatic void
660 X#if defined (CAN_PROTOTYPE)
661 XprintDiskInfo (void)
662 X#else
663 XprintDiskInfo ()
664 X#endif
665 X{
666 X    int                 i;
667 X    DiskInfo            totals;
668 X
669 X
670 X    memset ((char *) &totals, '\0', sizeof (DiskInfo));
671 X    strcpy (totals.name, "Total");
672 X    totals.printFlag = DI_OK;
673 X
674 X    if ((flags & DI_F_NO_HEADER) != DI_F_NO_HEADER)
675 X    {
676 X        printTitle ();
677 X    }
678 X
679 X    if (sortType != DI_SORT_NONE)
680 X    {
681 X        sortArray ((char *) diskInfo, sizeof (DiskInfo), diCount, diCompare);
682 X    }
683 X
684 X    for (i = 0; i < diCount; ++i)
685 X    {
686 X        if (( (flags & DI_F_ALL) == DI_F_ALL &&
687 X                diskInfo [i].printFlag != DI_BAD) ||
688 X                diskInfo [i].printFlag == DI_OK)
689 X        {
690 X            printInfo (&diskInfo [i]);
691 X            addTotals (&diskInfo [i], &totals);
692 X        }
693 X    }
694 X
695 X    if ((flags & DI_F_TOTAL) == DI_F_TOTAL &&
696 X            (flags & DI_F_NO_HEADER) != DI_F_NO_HEADER)
697 X    {
698 X        printInfo (&totals);
699 X    }
700 X}
701 X
702 X/*
703 X * printInfo
704 X *
705 X * Print the information for a single partition.  Loop through the
706 X * format string and print the particular items wanted.
707 X *
708 X */
709 X
710 Xstatic void
711 X#if defined (CAN_PROTOTYPE)
712 XprintInfo (DiskInfo *diskInfo)
713 X#else
714 XprintInfo (diskInfo)
715 X    DiskInfo            *diskInfo;
716 X#endif
717 X{
718 X    double              used;
719 X    double              totAvail;
720 X    char                *ptr;
721 X    int                 valid;
722 X
723 X
724 X    ptr = formatString;
725 X    while (*ptr)
726 X    {
727 X        valid = TRUE;
728 X
729 X        switch (*ptr)
730 X        {
731 X            case DI_FMT_MOUNT:
732 X            {
733 X                printf (DI_MOUNT_FMT, diskInfo->name);
734 X                break;
735 X            }
736 X
737 X            case DI_FMT_MOUNT_FULL:
738 X            {
739 X                printf (mountFormat, diskInfo->name);
740 X                break;
741 X            }
742 X
743 X            case DI_FMT_BTOT:
744 X            {
745 X                printf (blockFormat, diskInfo->totalBlocks);
746 X                break;
747 X            }
748 X
749 X            case DI_FMT_BTOT_AVAIL:
750 X            {
751 X                printf (blockFormat, diskInfo->totalBlocks -
752 X                        (diskInfo->freeBlocks - diskInfo->availBlocks));
753 X                break;
754 X            }
755 X
756 X            case DI_FMT_BUSED:
757 X            {
758 X                printf (blockFormat, diskInfo->totalBlocks -
759 X                        diskInfo->freeBlocks);
760 X                break;
761 X            }
762 X
763 X            case DI_FMT_BCUSED:
764 X            {
765 X                printf (blockFormat, diskInfo->totalBlocks - diskInfo->availBlocks);
766 X                break;
767 X            }
768 X
769 X            case DI_FMT_BFREE:
770 X            {
771 X                printf (blockFormat, diskInfo->freeBlocks);
772 X                break;
773 X            }
774 X
775 X            case DI_FMT_BAVAIL:
776 X            {
777 X                printf (blockFormat, diskInfo->availBlocks);
778 X                break;
779 X            }
780 X
781 X            case DI_FMT_BPERC_AVAIL:
782 X            {
783 X                used = diskInfo->totalBlocks - diskInfo->availBlocks;
784 X                totAvail = diskInfo->totalBlocks;
785 X                printPerc (used, totAvail, DI_PERC_FMT);
786 X                break;
787 X            }
788 X
789 X            case DI_FMT_BPERC_FREE:
790 X            {
791 X                used = diskInfo->totalBlocks - diskInfo->freeBlocks;
792 X                totAvail = diskInfo->totalBlocks;
793 X                printPerc (used, totAvail, DI_PERC_FMT);
794 X                break;
795 X            }
796 X
797 X            case DI_FMT_BPERC_BSD:
798 X            {
799 X                used = diskInfo->totalBlocks - diskInfo->freeBlocks;
800 X                totAvail = diskInfo->totalBlocks -
801 X                        (diskInfo->freeBlocks - diskInfo->availBlocks);
802 X                printPerc (used, totAvail, DI_PERC_FMT);
803 X                break;
804 X            }
805 X
806 X            case DI_FMT_ITOT:
807 X            {
808 X                printf (inodeFormat, diskInfo->totalInodes);
809 X                break;
810 X            }
811 X
812 X            case DI_FMT_IUSED:
813 X            {
814 X                printf (inodeFormat, diskInfo->totalInodes - diskInfo->freeInodes);
815 X                break;
816 X            }
817 X
818 X            case DI_FMT_IFREE:
819 X            {
820 X                printf (inodeFormat, diskInfo->freeInodes);
821 X                break;
822 X            }
823 X
824 X            case DI_FMT_IPERC:
825 X            {
826 X                used = diskInfo->totalInodes - diskInfo->availInodes;
827 X                totAvail = diskInfo->totalInodes;
828 X                printPerc (used, totAvail, DI_PERC_FMT);
829 X                break;
830 X            }
831 X
832 X            case DI_FMT_SPECIAL:
833 X            {
834 X                printf (DI_SPEC_FMT, diskInfo->special);
835 X                break;
836 X            }
837 X
838 X            case DI_FMT_SPECIAL_FULL:
839 X            {
840 X                printf (specialFormat, diskInfo->special);
841 X                break;
842 X            }
843 X
844 X            case DI_FMT_TYPE:
845 X            {
846 X                printf (DI_FSTYPE_FMT, diskInfo->fsType);
847 X                break;
848 X            }
849 X
850 X            case DI_FMT_TYPE_FULL:
851 X            {
852 X                printf (typeFormat, diskInfo->fsType);
853 X                break;
854 X            }
855 X
856 X            case DI_FMT_MOUNT_OPTIONS:
857 X            {
858 X                printf (optFormat, diskInfo->options);
859 X                break;
860 X            }
861 X
862 X            case DI_FMT_MOUNT_TIME:
863 X            {
864 X#if defined (HAS_MNT_TIME)
865 X                printf (mTimeFormat, diskInfo->mountTime);
866 X#endif
867 X                break;
868 X            }
869 X
870 X            default:
871 X            {
872 X                printf ("%c", *ptr);
873 X                valid = FALSE;
874 X                break;
875 X            }
876 X        }
877 X
878 X        ++ptr;
879 X        if (*ptr && valid)
880 X        {
881 X            printf (" ");
882 X        }
883 X    }
884 X
885 X    printf ("\n");
886 X}
887 X
888 X/*
889 X * addTotals
890 X *
891 X * Add up the totals for the blocks/inodes
892 X *
893 X */
894 X
895 Xstatic void
896 X#if defined (CAN_PROTOTYPE)
897 XaddTotals (DiskInfo *diskInfo, DiskInfo *totals)
898 X#else
899 XaddTotals (diskInfo, totals)
900 X    DiskInfo      *diskInfo;
901 X    DiskInfo      *totals;
902 X#endif
903 X{
904 X    totals->totalBlocks += diskInfo->totalBlocks;
905 X    totals->freeBlocks += diskInfo->freeBlocks;
906 X    totals->availBlocks += diskInfo->availBlocks;
907 X    totals->totalInodes += diskInfo->totalInodes;
908 X    totals->freeInodes += diskInfo->freeInodes;
909 X    totals->availInodes += diskInfo->availInodes;
910 X}
911 X
912 X/*
913 X * printTitle
914 X *
915 X * Loop through the format string and print the appropriate headings.
916 X *
917 X */
918 X
919 Xstatic void
920 X#if defined (CAN_PROTOTYPE)
921 XprintTitle (void)
922 X#else
923 XprintTitle ()
924 X#endif
925 X{
926 X    char                *ptr;
927 X    int                 valid;
928 X    char                tbuff [20];
929 X
930 X    if ((flags & DI_F_DEBUG_HDR) == DI_F_DEBUG_HDR)
931 X    {
932 X        printf ("di ver $Revision$ Default Format: %s\n",
933 X                DI_DEFAULT_FORMAT);
934 X    }
935 X
936 X    ptr = formatString;
937 X
938 X    while (*ptr)
939 X    {
940 X        valid = TRUE;
941 X
942 X        switch (*ptr)
943 X        {
944 X            case DI_FMT_MOUNT:
945 X            {
946 X                printf (DI_MOUNT_FMT, "Mount");
947 X                break;
948 X            }
949 X
950 X            case DI_FMT_MOUNT_FULL:
951 X            {
952 X                printf (mountFormat, "Mount");
953 X                break;
954 X            }
955 X
956 X            case DI_FMT_BTOT:
957 X            case DI_FMT_BTOT_AVAIL:
958 X            {
959 X                if (dispBlockSize == DI_ONE_K)
960 X                {
961 X                    printf (blockLabelFormat, "Kbytes");
962 X                }
963 X                else if (dispBlockSize == DI_ONE_MEG)
964 X                {
965 X                    printf (blockLabelFormat, "  Megs");
966 X                }
967 X                else if (dispBlockSize == DI_ONE_GIG)
968 X                {
969 X                    printf (blockLabelFormat, "  Gigs");
970 X                }
971 X                else if (dispBlockSize == DI_HALF_K)
972 X                {
973 X                    printf (blockLabelFormat, "  512b");
974 X                }
975 X                else
976 X                {
977 X                    sprintf (tbuff, "%6.0f", dispBlockSize);
978 X                    printf (blockLabelFormat, tbuff);
979 X                }
980 X                break;
981 X            }
982 X
983 X            case DI_FMT_BUSED:
984 X            case DI_FMT_BCUSED:
985 X            {
986 X                printf (blockLabelFormat, "Used");
987 X                break;
988 X            }
989 X
990 X            case DI_FMT_BFREE:
991 X            {
992 X                printf (blockLabelFormat, "Free");
993 X                break;
994 X            }
995 X
996 X            case DI_FMT_BAVAIL:
997 X            {
998 X                printf (blockLabelFormat, "Avail");
999 X                break;
1000 X            }
1001 X
1002 X            case DI_FMT_BPERC_AVAIL:
1003 X            case DI_FMT_BPERC_FREE:
1004 X            case DI_FMT_BPERC_BSD:
1005 X            {
1006 X                printf (DI_PERC_LBL_FMT, "%used");
1007 X                break;
1008 X            }
1009 X
1010 X            case DI_FMT_ITOT:
1011 X            {
1012 X                printf (inodeLabelFormat, "Inodes");
1013 X                break;
1014 X            }
1015 X
1016 X            case DI_FMT_IUSED:
1017 X            {
1018 X                printf (inodeLabelFormat, "Used");
1019 X                break;
1020 X            }
1021 X
1022 X            case DI_FMT_IFREE:
1023 X            {
1024 X                printf (inodeLabelFormat, "Free");
1025 X                break;
1026 X            }
1027 X
1028 X            case DI_FMT_IPERC:
1029 X            {
1030 X                printf (DI_PERC_LBL_FMT, "%used");
1031 X                break;
1032 X            }
1033 X
1034 X            case DI_FMT_SPECIAL:
1035 X            {
1036 X                printf (DI_SPEC_FMT, "Filesystem");
1037 X                break;
1038 X            }
1039 X
1040 X            case DI_FMT_SPECIAL_FULL:
1041 X            {
1042 X                printf (specialFormat, "Filesystem");
1043 X                break;
1044 X            }
1045 X
1046 X            case DI_FMT_TYPE:
1047 X            {
1048 X                printf (DI_FSTYPE_FMT, "fsType");
1049 X                break;
1050 X            }
1051 X
1052 X            case DI_FMT_TYPE_FULL:
1053 X            {
1054 X                printf (typeFormat, "fs Type");
1055 X                break;
1056 X            }
1057 X
1058 X            case DI_FMT_MOUNT_OPTIONS:
1059 X            {
1060 X                printf (optFormat, "Options");
1061 X                break;
1062 X            }
1063 X
1064 X            case DI_FMT_MOUNT_TIME:
1065 X            {
1066 X#if defined (HAS_MNT_TIME)
1067 X                printf (mTimeFormat, "Mount Time");
1068 X#endif
1069 X                break;
1070 X            }
1071 X
1072 X            default:
1073 X            {
1074 X                printf ("%c", *ptr);
1075 X                valid = FALSE;
1076 X                break;
1077 X            }
1078 X        }
1079 X
1080 X        ++ptr;
1081 X        if (*ptr && valid)
1082 X        {
1083 X            printf (" ");
1084 X        }
1085 X    }
1086 X
1087 X    printf ("\n");
1088 X}
1089 X
1090 X/*
1091 X * printPerc
1092 X *
1093 X * Calculate and print a percentage using the values and format passed.
1094 X *
1095 X */
1096 X
1097 Xstatic void
1098 X#if defined (CAN_PROTOTYPE)
1099 XprintPerc (double used, double totAvail, char *format)
1100 X#else
1101 XprintPerc (used, totAvail, format)
1102 X    double      used;
1103 X    double      totAvail;
1104 X    char        *format;
1105 X#endif
1106 X{
1107 X    double      perc;
1108 X
1109 X
1110 X    if (totAvail > 0.0)
1111 X    {
1112 X        perc = used / totAvail;
1113 X        perc *= 100.0;
1114 X    }
1115 X    else
1116 X    {
1117 X        perc = 0.0;
1118 X    }
1119 X    printf (format, perc);
1120 X}
1121 X
1122 X
1123 X/*
1124 X * Realloc
1125 X *
1126 X * portable realloc
1127 X *
1128 X */
1129 X
1130 Xstatic char *
1131 X#if defined (CAN_PROTOTYPE)
1132 XRealloc (char *ptr, long size)
1133 X#else
1134 XRealloc (ptr, size)
1135 X    char      *ptr;
1136 X    long      size;
1137 X#endif
1138 X{
1139 X    if (ptr == (char *) NULL)
1140 X    {
1141 X        ptr = (char *) malloc (size);
1142 X    }
1143 X    else
1144 X    {
1145 X        ptr = (char *) realloc (ptr, size);
1146 X    }
1147 X
1148 X    return ptr;
1149 X}
1150 X
1151 X
1152 Xstatic void
1153 X#if defined (CAN_PROTOTYPE)
1154 XprintFileInfo (int optind, int argc, char *argv [])
1155 X#else
1156 XprintFileInfo (optind, argc, argv)
1157 X    int                 optind;
1158 X    int                 argc;
1159 X    char                *argv [];
1160 X#endif
1161 X{
1162 X    int                 i;
1163 X    int                 j;
1164 X    struct stat         statBuf;
1165 X    DiskInfo            totals;
1166 X
1167 X
1168 X    memset ((char *) &totals, '\0', sizeof (DiskInfo));
1169 X    strcpy (totals.name, "Total");
1170 X    totals.printFlag = DI_OK;
1171 X
1172 X    if ((flags & DI_F_NO_HEADER) != DI_F_NO_HEADER)
1173 X    {
1174 X        printTitle ();
1175 X    }
1176 X
1177 X    for (i = optind; i < argc; ++i)
1178 X    {
1179 X        if (stat (argv [i], &statBuf) == 0)
1180 X        {
1181 X            for (j = 0; j < diCount; ++j)
1182 X            {
1183 X                if (diskInfo [j].printFlag != DI_BAD &&
1184 X                        diskInfo [j].st_dev != DI_UNKNOWN_DEV &&
1185 X                        (_ulong) statBuf.st_dev == diskInfo [j].st_dev)
1186 X                {
1187 X                    printInfo (&diskInfo [j]);
1188 X                    addTotals (&diskInfo [j], &totals);
1189 X                    break; /* out of inner for */
1190 X                }
1191 X            }
1192 X        } /* if stat ok */
1193 X        else
1194 X        {
1195 X            fprintf (stderr, "stat: %s ", argv[i]);
1196 X            perror ("");
1197 X        }
1198 X    } /* for each file specified on command line */
1199 X
1200 X    if ((flags & DI_F_TOTAL) == DI_F_TOTAL && (flags & DI_F_NO_HEADER) != DI_F_NO_HEADER)
1201 X    {
1202 X        printInfo (&totals);
1203 X    }
1204 X}
1205 X
1206 X/*
1207 X *  sortArray ()
1208 X *
1209 X *      shellsort!
1210 X *
1211 X */
1212 X
1213 Xstatic void
1214 X#if defined (CAN_PROTOTYPE)
1215 XsortArray (char *data, int dataSize, int count, DI_SORT_FUNC compareFunc)
1216 X#else
1217 XsortArray (data, dataSize, count, compareFunc)
1218 X    char            *data;
1219 X    int             dataSize;
1220 X    int             count;
1221 X    DI_SORT_FUNC    compareFunc;
1222 X#endif
1223 X{
1224 X    register int    j;
1225 X    char            *tempData;
1226 X    int             i;
1227 X    int             gap;
1228 X
1229 X
1230 X    if (count <= 1)
1231 X    {
1232 X        return;
1233 X    }
1234 X
1235 X    tempData = (char *) malloc ((unsigned) dataSize);
1236 X    if (tempData == (char *) NULL)
1237 X    {
1238 X        fprintf (stderr, "malloc failed in sortArray().  errno %d\n", errno);
1239 X        cleanup ();
1240 X        exit (1);
1241 X    }
1242 X
1243 X    gap = 1;
1244 X    while (gap < count)
1245 X    {
1246 X        gap = 3 * gap + 1;
1247 X    }
1248 X
1249 X    for (gap /= 3; gap > 0; gap /= 3)
1250 X    {
1251 X        for (i = gap; i < count; ++i)
1252 X        {
1253 X            memcpy ((char *) tempData, (char *) &(data [i * dataSize]),
1254 X                    dataSize);
1255 X            j = i - gap;
1256 X
1257 X            while (j >= 0 &&
1258 X                compareFunc (&(data [j * dataSize]), tempData) > 0)
1259 X            {
1260 X                memcpy ((char *) &(data [(j + gap) * dataSize]),
1261 X                        (char *) &(data [j * dataSize]), dataSize);
1262 X                j -= gap;
1263 X            }
1264 X
1265 X            j += gap;
1266 X            if (j != i)
1267 X            {
1268 X                memcpy ((char *) &(data [j * dataSize]),
1269 X                        (char *) tempData, dataSize);
1270 X            }
1271 X        }
1272 X    }
1273 X
1274 X    free ((char *) tempData);
1275 X}
1276 X
1277 X
1278 Xstatic int
1279 X#if defined (CAN_PROTOTYPE)
1280 XdiCompare (char *a, char *b)
1281 X#else
1282 XdiCompare (a, b)
1283 X    char        *a;
1284 X    char        *b;
1285 X#endif
1286 X{
1287 X    DiskInfo    *di1;
1288 X    DiskInfo    *di2;
1289 X
1290 X
1291 X    di1 = (DiskInfo *) a;
1292 X    di2 = (DiskInfo *) b;
1293 X
1294 X
1295 X    switch (sortType)
1296 X    {
1297 X        case DI_SORT_NONE:
1298 X        {
1299 X            break;
1300 X        }
1301 X
1302 X        case DI_SORT_NAME:
1303 X        {
1304 X            return (strcmp (di1->name, di2->name) * sortOrder);
1305 X        }
1306 X
1307 X        case DI_SORT_SPECIAL:
1308 X        {
1309 X            return (strcmp (di1->special, di2->special) * sortOrder);
1310 X        }
1311 X    } /* switch on sort type */
1312 X
1313 X    return 0;
1314 X}
1315 X
1316 X
1317 X/*
1318 X * getDiskStatInfo
1319 X *
1320 X * gets the disk device number for each entry.
1321 X *
1322 X */
1323 X
1324 Xstatic void
1325 X#if defined (CAN_PROTOTYPE)
1326 XgetDiskStatInfo (void)
1327 X#else
1328 XgetDiskStatInfo ()
1329 X#endif
1330 X{
1331 X    int         i;
1332 X    struct stat statBuf;
1333 X
1334 X    for (i = 0; i < diCount; ++i)
1335 X    {
1336 X        diskInfo [i].st_dev = (_ulong) DI_UNKNOWN_DEV;
1337 X
1338 X        if (stat (diskInfo [i].name, &statBuf) == 0)
1339 X        {
1340 X            diskInfo [i].st_dev = (_ulong) statBuf.st_dev;
1341 X            if (debug > 2)
1342 X            {
1343 X                printf ("dev: %s: %ld\n", diskInfo [i].name,
1344 X                    diskInfo [i].st_dev);
1345 X            }
1346 X        }
1347 X        else
1348 X        {
1349 X            fprintf (stderr, "stat: %s ", diskInfo [i].name);
1350 X            perror ("");
1351 X        }
1352 X    }
1353 X}
1354 X
1355 X/*
1356 X * getDiskSpecialInfo
1357 X *
1358 X * gets the disk device number for each entry.
1359 X *
1360 X */
1361 X
1362 Xstatic void
1363 X#if defined (CAN_PROTOTYPE)
1364 XgetDiskSpecialInfo (void)
1365 X#else
1366 XgetDiskSpecialInfo ()
1367 X#endif
1368 X{
1369 X    int         i;
1370 X    struct stat statBuf;
1371 X
1372 X    for (i = 0; i < diCount; ++i)
1373 X    {
1374 X        if (stat (diskInfo [i].special, &statBuf) == 0)
1375 X        {
1376 X            diskInfo [i].sp_dev = (_ulong) statBuf.st_dev;
1377 X            diskInfo [i].sp_rdev = (_ulong) statBuf.st_rdev;
1378 X            if (debug > 2)
1379 X            {
1380 X                printf ("special dev: %s: %ld rdev: %ld\n", diskInfo [i].special,
1381 X                        diskInfo [i].sp_dev, diskInfo [i].sp_rdev);
1382 X            }
1383 X        }
1384 X        else
1385 X        {
1386 X            diskInfo [i].sp_dev = 0;
1387 X            diskInfo [i].sp_rdev = 0;
1388 X        }
1389 X    }
1390 X}
1391 X
1392 X/*
1393 X * checkDiskInfo
1394 X *
1395 X * checks the disk information returned for various return values.
1396 X *
1397 X */
1398 X
1399 Xstatic void
1400 X#if defined (CAN_PROTOTYPE)
1401 XcheckDiskInfo (void)
1402 X#else
1403 XcheckDiskInfo ()
1404 X#endif
1405 X{
1406 X    int           i;
1407 X    int           j;
1408 X    int           dupCount;
1409 X    int           len;
1410 X    int           maxMountString;
1411 X    int           maxSpecialString;
1412 X    int           maxTypeString;
1413 X    int           maxOptString;
1414 X    int           maxMntTimeString;
1415 X    _fs_size_t    temp;
1416 X    _ulong        sp_dev;
1417 X    _ulong        sp_rdev;
1418 X
1419 X
1420 X    maxMountString = (flags & DI_F_NO_HEADER) == DI_F_NO_HEADER ? 0 : 5;
1421 X    maxSpecialString = (flags & DI_F_NO_HEADER) == DI_F_NO_HEADER ? 0 : 10;
1422 X    maxTypeString = (flags & DI_F_NO_HEADER) == DI_F_NO_HEADER ? 0 : 7;
1423 X    maxOptString = (flags & DI_F_NO_HEADER) == DI_F_NO_HEADER ? 0 : 7;
1424 X    maxMntTimeString = (flags & DI_F_NO_HEADER) == DI_F_NO_HEADER ? 0 : 26;
1425 X
1426 X    for (i = 0; i < diCount; ++i)
1427 X    {
1428 X            /* Solaris reports a cdrom as having no free blocks,   */
1429 X            /* no available.  Their df doesn't always work right!  */
1430 X            /* -1 is returned.                                     */
1431 X        if (debug > 2)
1432 X        {
1433 X            printf ("chk: %s free: %f\n", diskInfo [i].name,
1434 X                diskInfo [i].freeBlocks);
1435 X        }
1436 X        if (diskInfo [i].freeBlocks < 0.0)
1437 X        {
1438 X            diskInfo [i].freeBlocks = 0.0;
1439 X        }
1440 X        if (diskInfo [i].availBlocks < 0.0)
1441 X        {
1442 X            diskInfo [i].availBlocks = 0.0;
1443 X        }
1444 X
1445 X        temp = ~ 0;
1446 X        if (diskInfo [i].totalInodes == temp)
1447 X        {
1448 X            diskInfo [i].totalInodes = 0;
1449 X            diskInfo [i].freeInodes = 0;
1450 X            diskInfo [i].availInodes = 0;
1451 X        }
1452 X
1453 X        if (debug > 2)
1454 X        {
1455 X            printf ("chk: %s total: %f\n", diskInfo [i].name,
1456 X                    diskInfo [i].totalBlocks);
1457 X        }
1458 X        if (diskInfo [i].totalBlocks <= 0.0 &&
1459 X            diskInfo [i].printFlag != DI_BAD)
1460 X        {
1461 X            diskInfo [i].printFlag = DI_IGNORE;
1462 X            if (debug > 2)
1463 X            {
1464 X                printf ("chk: ignore: totalBlocks <= 0: %s\n",
1465 X                        diskInfo [i].name);
1466 X            }
1467 X        }
1468 X
1469 X        checkIgnoreList (&diskInfo [i]);
1470 X        checkIncludeList (&diskInfo [i]);
1471 X    } /* for all disks */
1472 X
1473 X        /* this loop sets duplicate entries to be ignored. */
1474 X    for (i = 0; i < diCount; ++i)
1475 X    {
1476 X            /* don't need to bother checking real partitions */
1477 X            /* don't bother if already ignored               */
1478 X        if (diskInfo [i].sp_rdev != 0 &&
1479 X            (diskInfo [i].printFlag == DI_OK ||
1480 X            ((flags & DI_F_ALL) == DI_F_ALL &&
1481 X            diskInfo [i].printFlag != DI_BAD)))
1482 X        {
1483 X            sp_dev = diskInfo [i].sp_dev;
1484 X            sp_rdev = diskInfo [i].sp_rdev;
1485 X            dupCount = 0;
1486 X
1487 X            for (j = 0; j < diCount; ++j)
1488 X            {
1489 X                if (diskInfo [j].sp_dev == sp_rdev)
1490 X                {
1491 X                    ++dupCount;
1492 X                }
1493 X            }
1494 X
1495 X            if (debug > 2)
1496 X            {
1497 X                printf ("dup: chk: %s %ld %ld dup: %d\n", diskInfo [i].name,
1498 X                    sp_dev, sp_rdev, dupCount);
1499 X            }
1500 X
1501 X            for (j = 0; dupCount > 0 && j < diCount; ++j)
1502 X            {
1503 X                if (diskInfo [j].sp_rdev == 0 &&
1504 X                    diskInfo [j].sp_dev == sp_rdev)
1505 X                {
1506 X                    diskInfo [j].printFlag = DI_IGNORE;
1507 X                    if (debug > 2)
1508 X                    {
1509 X                        printf ("chk: ignore: duplicate: %s\n",
1510 X                                diskInfo [j].name);
1511 X                    }
1512 X                }
1513 X            } /* duplicate check for each disk */
1514 X        } /* if this is a printable disk */
1515 X        else
1516 X        {
1517 X            if (debug > 2)
1518 X            {
1519 X                printf ("chk: dup: not checked: %s prnt: %d dev: %ld rdev: %ld\n",
1520 X                        diskInfo [i].name, diskInfo [i].printFlag,
1521 X                        diskInfo [i].sp_dev, diskInfo [i].sp_rdev);
1522 X            }
1523 X        }
1524 X    } /* for each disk */
1525 X
1526 X        /* this loop gets the max string lengths */
1527 X    for (i = 0; i < diCount; ++i)
1528 X    {
1529 X        if (diskInfo [i].printFlag == DI_OK || (flags & DI_F_ALL) == DI_F_ALL)
1530 X        {
1531 X            len = strlen (diskInfo [i].name);
1532 X            if (len > maxMountString)
1533 X            {
1534 X                maxMountString = len;
1535 X            }
1536 X
1537 X            len = strlen (diskInfo [i].special);
1538 X            if (len > maxSpecialString)
1539 X            {
1540 X                maxSpecialString = len;
1541 X            }
1542 X
1543 X            len = strlen (diskInfo [i].fsType);
1544 X            if (len > maxTypeString)
1545 X            {
1546 X                maxTypeString = len;
1547 X            }
1548 X
1549 X            len = strlen (diskInfo [i].options);
1550 X            if (len > maxOptString)
1551 X            {
1552 X                maxOptString = len;
1553 X            }
1554 X
1555 X            len = strlen (diskInfo [i].mountTime);
1556 X            if (len > maxMntTimeString)
1557 X            {
1558 X                maxMntTimeString = len;
1559 X            }
1560 X        } /* if we are printing this item */
1561 X    } /* for all disks */
1562 X
1563 X    sprintf (mountFormat, "%%-%d.%ds", maxMountString, maxMountString);
1564 X    sprintf (specialFormat, "%%-%d.%ds", maxSpecialString,
1565 X             maxSpecialString);
1566 X    sprintf (typeFormat, "%%-%d.%ds", maxTypeString, maxTypeString);
1567 X    sprintf (optFormat, "%%-%d.%ds", maxOptString, maxOptString);
1568 X    sprintf (mTimeFormat, "%%-%d.%ds", maxMntTimeString, maxMntTimeString);
1569 X
1570 X    if (dispBlockSize <= DI_ONE_K)
1571 X    {
1572 X        sprintf (blockFormat, "%%%d.0f", width);
1573 X    }
1574 X    else
1575 X    {
1576 X        sprintf (blockFormat, "%%%d.1f", width);
1577 X    }
1578 X    sprintf (blockLabelFormat, "%%%ds", width);
1579 X#if defined (HAS_64BIT_STATFS_FLDS)
1580 X    sprintf (inodeFormat, "%%%dllu", inodeWidth);
1581 X#else
1582 X    sprintf (inodeFormat, "%%%dlu", inodeWidth);
1583 X#endif
1584 X    sprintf (inodeLabelFormat, "%%%ds", inodeWidth);
1585 X}
1586 X
1587 X/*
1588 X * usage
1589 X *
1590 X */
1591 X
1592 Xstatic void
1593 X#if defined (CAN_PROTOTYPE)
1594 Xusage (void)
1595 X#else
1596 Xusage ()
1597 X#endif
1598 X{
1599 X    printf ("di ver $Revision$    Default Format: %s\n", DI_DEFAULT_FORMAT);
1600 X         /*  12345678901234567890123456789012345678901234567890123456789012345678901234567890 */
1601 X    printf ("Usage: di [-ant] [-f format] [-s sort-type] [-i ignore-fstyp-list]\n");
1602 X    printf ("       [-I include-fstyp-list] [-w kbyte-width] [-W inode-width] [file [...]]\n");
1603 X    printf ("   -a   : print all mounted devices; normally, those with 0 total blocks are\n");
1604 X    printf ("          not printed.  e.g. /dev/proc, /dev/fd.\n");
1605 X    printf ("   -d x : size to print blocks in (p - posix (512), k - kbytes,\n");
1606 X    printf ("          m - megabytes, g - gigabytes, <x> - numeric size).\n");
1607 X    printf ("   -f x : use format string <x>\n");
1608 X    printf ("   -i x : ignore file system types in <x>\n");
1609 X    printf ("   -I x : include only file system types in <x>\n");
1610 X    printf ("   -l   : display local filesystems only\n");
1611 X    printf ("   -n   : don't print header\n");
1612 X    printf ("   -s t : sort type; n - no sort, s - by special device, r - reverse\n");
1613 X    printf ("   -t   : print totals\n");
1614 X    printf ("   -w n : use width <n> for kbytes\n");
1615 X    printf ("   -W n : use width <n> for i-nodes\n");
1616 X    printf (" Format string values:\n");
1617 X    printf ("    m - mount point                     M - mount point, full length\n");
1618 X    printf ("    b - total kbytes                    B - kbytes available for use\n");
1619 X    printf ("    u - used kbytes                     c - calculated kbytes in use\n");
1620 X    printf ("    f - kbytes free                     v - kbytes available\n");
1621 X    printf ("    p - percentage not avail. for use   1 - percentage used\n");
1622 X    printf ("    2 - percentage of user-available space in use.\n");
1623 X    printf ("    i - total file slots (i-nodes)      U - used file slots\n");
1624 X    printf ("    F - free file slots                 P - percentage file slots used\n");
1625 X    printf ("    s - filesystem name                 S - filesystem name, full length\n");
1626 X    printf ("    t - disk partition type             T - partition type, full length\n");
1627 X}
1628 X
1629 X
1630 Xstatic void
1631 X#if defined (CAN_PROTOTYPE)
1632 XprocessArgs (int argc, char *argv [])
1633 X#else
1634 XprocessArgs (argc, argv)
1635 X    int         argc;
1636 X    char        *argv [];
1637 X#endif
1638 X{
1639 X    int         ch;
1640 X
1641 X
1642 X    while ((ch = getopt (argc, argv, "Aad:f:hi:I:Flns:tw:W:x:")) != -1)
1643 X    {
1644 X        switch (ch)
1645 X        {
1646 X            case 'A':
1647 X            {
1648 X                formatString = DI_ALL_FORMAT;
1649 X                flags |= DI_F_ALL | DI_F_DEBUG_HDR | DI_F_TOTAL;
1650 X                flags &= ~ DI_F_NO_HEADER;
1651 X                width = 10;
1652 X                inodeWidth = 10;
1653 X                break;
1654 X            }
1655 X
1656 X            case 'a':
1657 X            {
1658 X                flags |= DI_F_ALL;
1659 X                break;
1660 X            }
1661 X
1662 X            case 'd':
1663 X            {
1664 X                switch (tolower (*optarg))
1665 X                {
1666 X                    case 'p':
1667 X                    {
1668 X                        dispBlockSize = DI_HALF_K;
1669 X                        break;
1670 X                    }
1671 X
1672 X                    case 'k':
1673 X                    {
1674 X                        dispBlockSize = DI_ONE_K;
1675 X                        break;
1676 X                    }
1677 X
1678 X                    case 'm':
1679 X                    {
1680 X                        dispBlockSize = DI_ONE_MEG;
1681 X                        break;
1682 X                    }
1683 X
1684 X                    case 'g':
1685 X                    {
1686 X                        dispBlockSize = DI_ONE_GIG;
1687 X                        break;
1688 X                    }
1689 X
1690 X                    default:
1691 X                    {
1692 X                        if (isdigit ((int) (*optarg)))
1693 X                        {
1694 X                            dispBlockSize = atof (optarg);
1695 X                        }
1696 X                        break;
1697 X                    }
1698 X                }
1699 X                break;
1700 X            }
1701 X
1702 X            case 'f':
1703 X            {
1704 X                formatString = optarg;
1705 X                break;
1706 X            }
1707 X
1708 X            case 'h':
1709 X            {
1710 X                usage ();
1711 X                cleanup ();
1712 X                exit (0);
1713 X            }
1714 X
1715 X            case 'i':
1716 X            {
1717 X                parseList (&ignoreList, optarg);
1718 X                break;
1719 X            }
1720 X
1721 X            case 'I':
1722 X            {
1723 X                parseList (&includeList, optarg);
1724 X                break;
1725 X            }
1726 X
1727 X            case 'l':
1728 X            {
1729 X                flags |= DI_F_LOCAL_ONLY;
1730 X                break;
1731 X            }
1732 X
1733 X            case 'n':
1734 X            {
1735 X                flags |= DI_F_NO_HEADER;
1736 X                break;
1737 X            }
1738 X
1739 X            case 's':
1740 X            {
1741 X                switch (ch)
1742 X                {
1743 X                    case 's':
1744 X                    {
1745 X                        sortType = DI_SORT_SPECIAL;
1746 X                        break;
1747 X                    }
1748 X
1749 X                    case 'n':
1750 X                    {
1751 X                        sortType = DI_SORT_NONE;
1752 X                        break;
1753 X                    }
1754 X
1755 X                    case 'r':
1756 X                    {
1757 X                        sortOrder = DI_SORT_DESCENDING;
1758 X                        break;
1759 X                    }
1760 X                }
1761 X                break;
1762 X            }
1763 X
1764 X            case 't':
1765 X            {
1766 X                flags |= DI_F_TOTAL;
1767 X                break;
1768 X            }
1769 X
1770 X            case 'w':
1771 X            {
1772 X                width = atoi (optarg);
1773 X                break;
1774 X            }
1775 X
1776 X            case 'W':
1777 X            {
1778 X                inodeWidth = atoi (optarg);
1779 X                break;
1780 X            }
1781 X
1782 X            case 'x':
1783 X            {
1784 X                debug = atoi (optarg);
1785 X                break;
1786 X            }
1787 X
1788 X            case '?':
1789 X            {
1790 X                usage ();
1791 X                cleanup ();
1792 X                exit (1);
1793 X            }
1794 X        }
1795 X    }
1796 X}
1797 X
1798 X    /* list is assumed to be global */
1799 Xstatic void
1800 X#if defined (CAN_PROTOTYPE)
1801 XparseList (char ***list, char *str)
1802 X#else
1803 XparseList (list, str)
1804 X    char        ***list;
1805 X    char        *str;
1806 X#endif
1807 X{
1808 X    char        *dstr;
1809 X    char        *ptr;
1810 X    char        **lptr;
1811 X    int         count;
1812 X    int         i;
1813 X    int         len;
1814 X
1815 X    i = strlen (str);
1816 X    dstr = (char *) malloc (i + 1);
1817 X    if (dstr == (char *) NULL)
1818 X    {
1819 X        fprintf (stderr, "malloc failed in parseList() (1).  errno %d\n", errno);
1820 X        cleanup ();
1821 X        exit (1);
1822 X    }
1823 X
1824 X    memcpy (dstr, str, i + 1);
1825 X
1826 X    ptr = strtok (dstr, DI_LIST_SEP);
1827 X    count = 0;
1828 X    while (ptr != (char *) NULL)
1829 X    {
1830 X        ++count;
1831 X        ptr = strtok ((char *) NULL, DI_LIST_SEP);
1832 X    }
1833 X
1834 X    *list = (char **) malloc ((count + 1) * sizeof (char *));
1835 X    if (*list == (char **) NULL)
1836 X    {
1837 X        fprintf (stderr, "malloc failed in parseList() (2).  errno %d\n", errno);
1838 X        cleanup ();
1839 X        exit (1);
1840 X    }
1841 X
1842 X    ptr = dstr;
1843 X    lptr = *list;
1844 X    for (i = 0; i < count; ++i)
1845 X    {
1846 X        len = strlen (ptr);
1847 X        *lptr = (char *) malloc (len + 1);
1848 X        if (*lptr == (char *) NULL)
1849 X        {
1850 X            fprintf (stderr, "malloc failed in parseList() (3).  errno %d\n",
1851 X                    errno);
1852 X            cleanup ();
1853 X            exit (1);
1854 X        }
1855 X        strcpy (*lptr, ptr);
1856 X        ptr += len + 1;
1857 X        ++lptr;
1858 X    }
1859 X
1860 X    *lptr = (char *) NULL;
1861 X    free ((char *) dstr);
1862 X}
1863 X
1864 X
1865 Xstatic void
1866 X#if defined (CAN_PROTOTYPE)
1867 XcheckIgnoreList (DiskInfo *diskInfo)
1868 X#else
1869 XcheckIgnoreList (diskInfo)
1870 X    DiskInfo        *diskInfo;
1871 X#endif
1872 X{
1873 X    char            **ptr;
1874 X
1875 X        /* if the file system type is in the ignore list, skip it */
1876 X    if (ignoreList != (char **) NULL)
1877 X    {
1878 X        ptr = ignoreList;
1879 X        while (*ptr != (char *) NULL)
1880 X        {
1881 X            if (strcmp (*ptr, diskInfo->fsType) == 0)
1882 X            {
1883 X                diskInfo->printFlag = DI_IGNORE;
1884 X                if (debug > 2)
1885 X                {
1886 X                    printf ("chkign: ignore: fstype %s match: %s\n", *ptr,
1887 X                            diskInfo->name);
1888 X                }
1889 X                break;
1890 X            }
1891 X            ++ptr;
1892 X        }
1893 X    } /* if an ignore list was specified */
1894 X}
1895 X
1896 Xstatic void
1897 X#if defined (CAN_PROTOTYPE)
1898 XcheckIncludeList (DiskInfo *diskInfo)
1899 X#else
1900 XcheckIncludeList (diskInfo)
1901 X    DiskInfo        *diskInfo;
1902 X#endif
1903 X{
1904 X    char            **ptr;
1905 X
1906 X        /* if the file system type is not in the include list, skip it */
1907 X    if (includeList != (char **) NULL)
1908 X    {
1909 X        ptr = includeList;
1910 X        while (*ptr != (char *) NULL)
1911 X        {
1912 X            if (strcmp (*ptr, diskInfo->fsType) == 0)
1913 X            {
1914 X                diskInfo->printFlag = DI_OK;
1915 X                break;
1916 X            }
1917 X            else
1918 X            {
1919 X                diskInfo->printFlag = DI_IGNORE;
1920 X                if (debug > 2)
1921 X                {
1922 X                    printf ("chkinc: ! include: fstype %s match: %s\n", *ptr,
1923 X                            diskInfo->name);
1924 X                }
1925 X            }
1926 X            ++ptr;
1927 X        }
1928 X    } /* if an include list was specified */
1929 X}
1930 X
1931 X
1932 X#if defined (HAS_FS_INFO)
1933 X
1934 X/*
1935 X * getDiskEntries
1936 X *
1937 X * For BeOS.
1938 X *
1939 X */
1940 X
1941 Xstatic int
1942 XgetDiskEntries (void)
1943 X{
1944 X    status_t        stat;
1945 X    int             idx;
1946 X    int32           count;
1947 X    dev_t           dev;
1948 X    char            buff [B_FILE_NAME_LENGTH];
1949 X    fs_info         fsinfo;
1950 X    double          mult;
1951 X    node_ref        nref;
1952 X    BDirectory      *dir;
1953 X    BEntry          entry;
1954 X    BPath           path;
1955 X
1956 X    count = 0;
1957 X    while ((dev = next_dev (&count)) != B_BAD_VALUE)
1958 X    {
1959 X        if ((stat = fs_stat_dev (dev, &fsinfo)) == B_BAD_VALUE)
1960 X        {
1961 X            break;
1962 X        }
1963 X
1964 X        idx = diCount;
1965 X        ++diCount;
1966 X        diskInfo = (DiskInfo *) Realloc ((char *) diskInfo,
1967 X                sizeof (DiskInfo) * diCount);
1968 X        memset ((char *) &diskInfo [idx], '\0', sizeof (DiskInfo));
1969 X        diskInfo [idx].printFlag = DI_OK;
1970 X        *buff = '\0';
1971 X        nref.device = dev;
1972 X        nref.node = fsinfo.root;
1973 X        dir = new BDirectory (&nref);
1974 X        stat = dir->GetEntry (&entry);
1975 X        stat = entry.GetPath (&path);
1976 X        strncpy (diskInfo [idx].name, path.Path (), DI_NAME_LEN);
1977 X        strncpy (diskInfo [idx].special, fsinfo.device_name, DI_SPEC_NAME_LEN);
1978 X        strncpy (diskInfo [idx].fsType, fsinfo.fsh_name, DI_TYPE_LEN);
1979 X        diskInfo [idx].isLocal = TRUE;
1980 X        mult = (double) (long) fsinfo.block_size / dispBlockSize;
1981 X        diskInfo [idx].totalBlocks =
1982 X                ((double) (_s_fs_size_t) fsinfo.total_blocks * mult);
1983 X        diskInfo [idx].freeBlocks =
1984 X                ((double) (_s_fs_size_t) fsinfo.free_blocks * mult);
1985 X        diskInfo [idx].availBlocks =
1986 X                ((double) (_s_fs_size_t) fsinfo.free_blocks * mult);
1987 X        diskInfo [idx].totalInodes = fsinfo.total_nodes;
1988 X        diskInfo [idx].freeInodes = fsinfo.free_nodes;
1989 X        diskInfo [idx].availInodes = fsinfo.free_nodes;
1990 X
1991 X        checkIgnoreList (&diskInfo [idx]);
1992 X        checkIncludeList (&diskInfo [idx]);
1993 X
1994 X        if (debug > 0)
1995 X        {
1996 X            printf ("mnt:%s - %s\n", diskInfo [idx].name,
1997 X                    diskInfo [idx].special);
1998 X            printf ("dev:%d fs:%s\n", dev, diskInfo [idx].fsType);
1999 X        }
2000 X        if (debug > 1)
2001 X        {
2002 X            printf ("%s: %s\n", diskInfo [idx].name, diskInfo [idx].fsType);
2003 X            printf ("\tmult:%f\n", mult);
2004 X            printf ("\tblocks: tot:%ld free:%ld\n",
2005 X                    fsinfo.total_blocks, fsinfo.free_blocks);
2006 X            printf ("\tinodes: tot:%ld free:%ld\n",
2007 X                    fsinfo.total_nodes, fsinfo.free_nodes);
2008 X        }
2009 X    }
2010 X    return 0;
2011 X}
2012 X
2013 Xstatic void
2014 XgetDiskInfo (void)
2015 X{
2016 X    return;
2017 X}
2018 X
2019 X#endif
2020 X
2021 X#if defined (HAS_GETMNTENT) && ! defined (HAS_SETMNTENT)
2022 X
2023 X# define DFS_FS_TABLE        "/etc/dfs/fstypes"
2024 X
2025 X/*
2026 X * getDiskEntries
2027 X *
2028 X * For SysV.4, we open the file and call getmntent () repeatedly.
2029 X *
2030 X */
2031 X
2032 Xstatic int
2033 XgetDiskEntries ()
2034 X{
2035 X    FILE            *f;
2036 X    int             idx;
2037 X    int             i;
2038 X    struct mnttab   mntEntry;
2039 X    char            buff [80];
2040 X    time_t          mtime;
2041 X    char            *devp;   /* local ptr to dev entry */
2042 X
2043 X
2044 X    if ((flags & DI_F_LOCAL_ONLY) == DI_F_LOCAL_ONLY)
2045 X    {
2046 X        i = remoteFileSystemCount;
2047 X
2048 X        if ((f = fopen (DFS_FS_TABLE, "r")) != (FILE *) NULL)
2049 X        {
2050 X            fgets (buff, 80, f);
2051 X            if (debug > 1)
2052 X            {
2053 X                printf ("remote file system type: %s\n", buff);
2054 X            }
2055 X            sscanf (buff, "%s", remoteFileSystemTypes [i++]);
2056 X            fclose (f);
2057 X        }
2058 X
2059 X        remoteFileSystemCount = i;
2060 X    }
2061 X
2062 X    if ((f = fopen (DI_MOUNT_FILE, "r")) == (FILE *) NULL)
2063 X    {
2064 X        fprintf (stderr, "Unable to open: %s errno %d\n", DI_MOUNT_FILE, errno);
2065 X        return -1;
2066 X    }
2067 X
2068 X    while (getmntent (f, &mntEntry) == 0)
2069 X    {
2070 X        idx = diCount;
2071 X        ++diCount;
2072 X        diskInfo = (DiskInfo *) Realloc ((char *) diskInfo,
2073 X                sizeof (DiskInfo) * diCount);
2074 X        memset ((char *) &diskInfo [idx], '\0', sizeof (DiskInfo));
2075 X        diskInfo [idx].printFlag = DI_OK;
2076 X
2077 X        strncpy (diskInfo [idx].special, mntEntry.mnt_special,
2078 X                DI_SPEC_NAME_LEN);
2079 X        strncpy (diskInfo [idx].name, mntEntry.mnt_mountp, DI_NAME_LEN);
2080 X# if defined (MNTOPT_IGNORE)
2081 X        if (strstr (mntEntry.mnt_mntopts, MNTOPT_IGNORE) != (char *) NULL)
2082 X# else
2083 X        if (strstr (mntEntry.mnt_mntopts, "ignore") != (char *) NULL)
2084 X# endif
2085 X        {
2086 X            diskInfo [idx].printFlag = DI_IGNORE;
2087 X            if (debug > 2)
2088 X            {
2089 X                printf ("mnt: ignore: mntopt 'ignore': %s\n",
2090 X                        diskInfo [idx].name);
2091 X            }
2092 X        }
2093 X# if defined (MNTOPT_DEV)
2094 X        sprintf (buff, "%s=", MNTOPT_DEV);
2095 X        if ((devp = strstr (mntEntry.mnt_mntopts, buff)) != (char *) NULL)
2096 X# else
2097 X        if ((devp = strstr (mntEntry.mnt_mntopts, "dev=")) != (char *) NULL)
2098 X# endif
2099 X        {
2100 X            if (devp != mntEntry.mnt_mntopts)
2101 X            {
2102 X                --devp;
2103 X            }
2104 X            *devp = 0;   /* point to preceeding comma and cut off */
2105 X        }
2106 X        strncpy (diskInfo [idx].options, mntEntry.mnt_mntopts, DI_OPT_LEN);
2107 X        mtime = atol (mntEntry.mnt_time);
2108 X        strncpy (diskInfo [idx].mountTime, ctime (&mtime), DI_MNT_TIME_LEN);
2109 X
2110 X            /* get the file system type now... */
2111 X        strncpy (diskInfo [idx].fsType, mntEntry.mnt_fstype, DI_TYPE_LEN);
2112 X
2113 X        diskInfo [idx].isLocal = TRUE;
2114 X        for (i = 0; i < remoteFileSystemCount; ++i)
2115 X        {
2116 X            if (strcmp (diskInfo [idx].fsType, remoteFileSystemTypes [i]) == 0)
2117 X            {
2118 X                diskInfo [idx].isLocal = FALSE;
2119 X            }
2120 X        }
2121 X
2122 X        checkIgnoreList (&diskInfo [idx]);
2123 X        checkIncludeList (&diskInfo [idx]);
2124 X
2125 X        if (debug > 0)
2126 X        {
2127 X            printf ("mnt:%s - %s\n", diskInfo [idx].name,
2128 X                    diskInfo [idx].special);
2129 X        }
2130 X    }
2131 X
2132 X    fclose (f);
2133 X    return 0;
2134 X}
2135 X
2136 X#endif /* HAS_GETMNTENT */
2137 X
2138 X#if ! defined (HAS_GETMNTENT) && ! defined (HAS_MNTCTL) && \
2139 X        ! defined (HAS_GETMNTINFO) && ! defined (HAS_GETMNT) && \
2140 X       ! defined (HAS_GETDISKFREESPACE) && ! defined (HAS_FS_INFO)
2141 X
2142 X/*
2143 X * getDiskEntries
2144 X *
2145 X * For SysV.3 we open the file and read it ourselves.
2146 X *
2147 X */
2148 X
2149 Xstatic int
2150 XgetDiskEntries ()
2151 X{
2152 X    FILE             *f;
2153 X    int              idx;
2154 X    struct mnttab    mntEntry;
2155 X
2156 X
2157 X    if ((f = fopen (DI_MOUNT_FILE, "r")) == (FILE *) NULL)
2158 X    {
2159 X        fprintf (stderr, "Unable to open: %s errno %d\n", DI_MOUNT_FILE, errno);
2160 X        return -1;
2161 X    }
2162 X
2163 X    while (fread ((char *) &mntEntry, sizeof (struct mnttab), 1, f) == 1)
2164 X    {
2165 X            /* xenix allows null mount table entries */
2166 X            /* sco nfs background mounts are marked as "nothing" */
2167 X        if (mntEntry.mt_filsys [0] &&
2168 X                strcmp (mntEntry.mt_filsys, "nothing") != 0)
2169 X        {
2170 X            idx = diCount;
2171 X            ++diCount;
2172 X            diskInfo = (DiskInfo *) Realloc ((char *) diskInfo,
2173 X                                             sizeof (DiskInfo) * diCount);
2174 X            memset ((char *) &diskInfo [idx], '\0', sizeof (DiskInfo));
2175 X            diskInfo [idx].printFlag = DI_OK;
2176 X            diskInfo [idx].isLocal = TRUE;
2177 X
2178 X# if defined (COHERENT)
2179 X                /* Coherent seems to have these fields reversed. oh well. */
2180 X            strncpy (diskInfo [idx].name, mntEntry.mt_dev, DI_NAME_LEN);
2181 X            strncpy (diskInfo [idx].special, mntEntry.mt_filsys, DI_SPEC_NAME_LEN);
2182 X# else
2183 X            strncpy (diskInfo [idx].special, mntEntry.mt_dev, DI_SPEC_NAME_LEN);
2184 X            strncpy (diskInfo [idx].name, mntEntry.mt_filsys, DI_NAME_LEN);
2185 X# endif
2186 X            strncpy (diskInfo [idx].options, mntEntry.mnt_mntopts, DI_OPT_LEN);
2187 X            strncpy (diskInfo [idx].mountTime, mntEntry.mnt_time,
2188 X                    DI_MNT_TIME_LEN);
2189 X        }
2190 X
2191 X        if (debug > 0)
2192 X        {
2193 X            printf ("mnt:%s - %s\n", diskInfo [idx].name,
2194 X                    diskInfo [idx].special);
2195 X        }
2196 X    }
2197 X
2198 X    fclose (f);
2199 X    return 0;
2200 X}
2201 X
2202 X#endif /* Sys V.3 */
2203 X
2204 X#if defined (HAS_GETMNTENT) && defined (HAS_SETMNTENT) && \
2205 X        defined (HAS_ENDMNTENT)
2206 X
2207 X/*
2208 X * getDiskEntries
2209 X *
2210 X * SunOS supplies an open and close routine for the mount table.
2211 X *
2212 X */
2213 X
2214 Xstatic int
2215 XgetDiskEntries ()
2216 X{
2217 X    FILE            *f;
2218 X    int             idx;
2219 X    struct mntent   *mntEntry;
2220 X    char            *devp;   /* local ptr to dev entry */
2221 X
2222 X
2223 X#if defined (HAS_SETMNTENT_ONE_ARG)
2224 X    if ((f = setmntent (DI_MOUNT_FILE)) == (FILE *) NULL)
2225 X#else
2226 X    if ((f = setmntent (DI_MOUNT_FILE, "r")) == (FILE *) NULL)
2227 X#endif
2228 X    {
2229 X        fprintf (stderr, "Unable to open: %s errno %d\n", DI_MOUNT_FILE, errno);
2230 X        return -1;
2231 X    }
2232 X
2233 X    while ((mntEntry = getmntent (f)) != (struct mntent *) NULL)
2234 X    {
2235 X        idx = diCount;
2236 X        ++diCount;
2237 X        diskInfo = (DiskInfo *) Realloc ((char *) diskInfo,
2238 X                sizeof (DiskInfo) * diCount);
2239 X        memset ((char *) &diskInfo [idx], '\0', sizeof (DiskInfo));
2240 X        diskInfo [idx].printFlag = DI_OK;
2241 X        diskInfo [idx].isLocal = TRUE;
2242 X
2243 X        strncpy (diskInfo [idx].special, mntEntry->mnt_fsname, DI_SPEC_NAME_LEN);
2244 X        strncpy (diskInfo [idx].name, mntEntry->mnt_dir, DI_NAME_LEN);
2245 X        strncpy (diskInfo [idx].fsType, mntEntry->mnt_type, DI_TYPE_LEN);
2246 X
2247 X        if (strcmp (mntEntry->mnt_type, MNTTYPE_IGNORE) == 0)
2248 X        {
2249 X            diskInfo [idx].printFlag = DI_IGNORE;
2250 X            if (debug > 2)
2251 X            {
2252 X                printf ("mnt: ignore: mntopt 'ignore': %s\n",
2253 X                        diskInfo [idx].name);
2254 X            }
2255 X        }
2256 X
2257 X        if ((devp = strstr (mntEntry->mnt_opts, "dev=")) != (char *) NULL)
2258 X        {
2259 X            if (devp != mntEntry->mnt_opts)
2260 X            {
2261 X                --devp;
2262 X            }
2263 X            *devp = 0;   /* point to preceeding comma and cut off */
2264 X        }
2265 X        strncpy (diskInfo [idx].options, mntEntry->mnt_opts, DI_OPT_LEN);
2266 X
2267 X        checkIgnoreList (&diskInfo [idx]);
2268 X        checkIncludeList (&diskInfo [idx]);
2269 X
2270 X        if (debug > 0)
2271 X        {
2272 X            printf ("mnt:%s - %s : %s\n", diskInfo [idx].name,
2273 X                    diskInfo [idx].special, diskInfo [idx].fsType);
2274 X        }
2275 X    }
2276 X
2277 X    endmntent (f);
2278 X    return 0;
2279 X}
2280 X
2281 X#endif /* HAS_GETMNTENT && HAS_SETMNTENT && HAS_ENDMNTENT */
2282 X
2283 X#if defined (HAS_GETMNTINFO)
2284 X
2285 X/*
2286 X * getDiskEntries
2287 X *
2288 X * OSF/1 does this with a system call and library routine
2289 X *
2290 X *                  [mogul@wrl.dec.com (Jeffrey Mogul)]
2291 X */
2292 X
2293 X#if defined (INITMOUNTNAMES)
2294 Xstatic char *mnt_names [] = INITMOUNTNAMES;
2295 X# define MNT_NUMTYPES (MOUNT_MAXTYPE + 1)
2296 X#endif
2297 X
2298 X    /* osf/1 mount flags start w/M_ vs. MNT_     */
2299 X    /* this saves us from lots of duplicate code */
2300 X#if defined (M_RDONLY)
2301 X# define MNT_RDONLY M_RDONLY
2302 X#endif
2303 X#if defined (M_SYNCHRONOUS)
2304 X# define MNT_SYNCHRONOUS M_SYNCHRONOUS
2305 X#endif
2306 X#if defined (M_NOEXEC)
2307 X# define MNT_NOEXEC M_NOEXEC
2308 X#endif
2309 X#if defined (M_NOSUID)
2310 X# define MNT_NOSUID M_NOSUID
2311 X#endif
2312 X#if defined (M_NODEV)
2313 X# define MNT_NODEV M_NODEV
2314 X#endif
2315 X#if defined (M_GRPID)
2316 X# define MNT_GRPID M_GRPID
2317 X#endif
2318 X#if defined (M_EXPORTED)
2319 X# define MNT_EXPORTED M_EXPORTED
2320 X#endif
2321 X#if defined (M_EXRDONLY)
2322 X# define MNT_EXRDONLY M_EXRDONLY
2323 X#endif
2324 X#if defined (M_EXRDMOSTLY)
2325 X# define MNT_EXRDMOSTLY M_EXRDMOSTLY
2326 X#endif
2327 X#if defined (M_SECURE)
2328 X# define MNT_SECURE M_SECURE
2329 X#endif
2330 X#if defined (M_LOCAL)
2331 X# define MNT_LOCAL M_LOCAL
2332 X#endif
2333 X#if defined (M_QUOTA)
2334 X# define MNT_QUOTA M_QUOTA
2335 X#endif
2336 X
2337 Xstatic int
2338 XgetDiskEntries ()
2339 X{
2340 X    int             count;
2341 X    int             idx;
2342 X    int             len;
2343 X    short           fstype;
2344 X    struct statfs   *mntbufp;
2345 X    double          mult;
2346 X
2347 X    count = getmntinfo (&mntbufp, MNT_WAIT);
2348 X    if (count < 1)
2349 X    {
2350 X        fprintf (stderr, "Unable to do getmntinfo () errno %d\n", errno);
2351 X        return -1;
2352 X    }
2353 X
2354 X    diCount = count;
2355 X    diskInfo = (DiskInfo *) malloc (sizeof (DiskInfo) * count);
2356 X    if (diskInfo == (DiskInfo *) NULL)
2357 X    {
2358 X        fprintf (stderr, "malloc failed for diskInfo. errno %d\n", errno);
2359 X        return -1;
2360 X    }
2361 X    memset ((char *) diskInfo, '\0', sizeof (DiskInfo) * count);
2362 X
2363 X    if (debug > 1)
2364 X    {
2365 X        printf ("type_len %d name_len %d spec_name_len %d\n", DI_TYPE_LEN,
2366 X                DI_NAME_LEN, DI_SPEC_NAME_LEN);
2367 X    }
2368 X
2369 X    for (idx = 0; idx < count; idx++)
2370 X    {
2371 X        diskInfo [idx].printFlag = DI_OK;
2372 X        diskInfo [idx].isLocal = FALSE;
2373 X#if defined (MNT_LOCAL)
2374 X        if ((mntbufp [idx].f_flags & MNT_LOCAL) == MNT_LOCAL)
2375 X        {
2376 X            diskInfo [idx].isLocal = TRUE;
2377 X        }
2378 X#endif
2379 X
2380 X        if (diskInfo [idx].isLocal == FALSE &&
2381 X                (flags & DI_F_LOCAL_ONLY) == DI_F_LOCAL_ONLY)
2382 X        {
2383 X            diskInfo [idx].printFlag = DI_IGNORE;
2384 X            if (debug > 2)
2385 X            {
2386 X                printf ("mnt: ignore: remote: %s\n",
2387 X                        diskInfo [idx].name);
2388 X            }
2389 X        }
2390 X
2391 X        strncpy (diskInfo [idx].special, mntbufp [idx].f_mntfromname,
2392 X                DI_SPEC_NAME_LEN);
2393 X        strncpy (diskInfo [idx].name, mntbufp [idx].f_mntonname, DI_NAME_LEN);
2394 X
2395 X        mult = 1.0;
2396 X
2397 X#  if defined (HAS_GETMNTINFO_FSIZE) /* 1.x */
2398 X        mult = (double) mntbufp [idx].f_fsize / dispBlockSize;
2399 X#  endif
2400 X#  if defined (HAS_GETMNTINFO_BSIZE) /* 2.x */
2401 X        mult = (double) mntbufp [idx].f_bsize / dispBlockSize;
2402 X#  endif
2403 X        diskInfo [idx].totalBlocks = ((double) (_s_fs_size_t) mntbufp [idx].f_blocks * mult);
2404 X        diskInfo [idx].freeBlocks = ((double) (_s_fs_size_t) mntbufp [idx].f_bfree * mult);
2405 X        diskInfo [idx].availBlocks = ((double) (_s_fs_size_t) mntbufp [idx].f_bavail * mult);
2406 X
2407 X        diskInfo [idx].totalInodes = mntbufp [idx].f_files;
2408 X        diskInfo [idx].freeInodes = mntbufp [idx].f_ffree;
2409 X        diskInfo [idx].availInodes = mntbufp [idx].f_ffree;
2410 X
2411 X        fstype = mntbufp [idx].f_type;
2412 X# if ! defined (I_SYS_FSTYP) && ! defined (INITMOUNTNAMES) && \
2413 X    ! defined (HAS_GETMNTINFO_FSTYPENAME)
2414 X        if ((fstype >= 0) && (fstype <= MOUNT_MAXTYPE))
2415 X        {
2416 X            switch (fstype)
2417 X            {
2418 X#  if defined (MOUNT_NONE)
2419 X                case MOUNT_NONE:         /* No Filesystem */
2420 X                {
2421 X                    strncpy (diskInfo [idx].fsType, "none", DI_TYPE_LEN);
2422 X                    break;
2423 X                }
2424 X#  endif
2425 X
2426 X#  if defined (MOUNT_UFS)
2427 X                case MOUNT_UFS:         /* UNIX "Fast" Filesystem */
2428 X                {
2429 X                    strncpy (diskInfo [idx].fsType, "ufs", DI_TYPE_LEN);
2430 X                    break;
2431 X                }
2432 X#  endif
2433 X
2434 X#  if defined (MOUNT_NFS)
2435 X                case MOUNT_NFS:         /* Network Filesystem */
2436 X                {
2437 X                    strncpy (diskInfo [idx].fsType, "nfs", DI_TYPE_LEN);
2438 X                    break;
2439 X                }
2440 X#  endif
2441 X
2442 X#  if defined (MOUNT_MFS)
2443 X                case MOUNT_MFS:         /* Memory Filesystem */
2444 X                {
2445 X                    strncpy (diskInfo [idx].fsType, "mfs", DI_TYPE_LEN);
2446 X                    break;
2447 X                }
2448 X#  endif
2449 X
2450 X#  if defined (MOUNT_MSDOS)
2451 X                case MOUNT_MSDOS:       /* MSDOS Filesystem */
2452 X                {
2453 X                    strncpy (diskInfo [idx].fsType, "msdos", DI_TYPE_LEN);
2454 X                    break;
2455 X                }
2456 X#  endif
2457 X
2458 X#  if defined (MOUNT_LFS)
2459 X                case MOUNT_LFS:
2460 X                {
2461 X                    strncpy (diskInfo [idx].fsType, "lfs", DI_TYPE_LEN);
2462 X                    break;
2463 X                }
2464 X#  endif
2465 X
2466 X#  if defined (MOUNT_LOFS)
2467 X                case MOUNT_LOFS:
2468 X                {
2469 X                    strncpy (diskInfo [idx].fsType, "lofs", DI_TYPE_LEN);
2470 X                    break;
2471 X                }
2472 X#  endif
2473 X
2474 X#  if defined (MOUNT_FDESC)
2475 X                case MOUNT_FDESC:
2476 X                {
2477 X                    strncpy (diskInfo [idx].fsType, "fdesc", DI_TYPE_LEN);
2478 X                    break;
2479 X                }
2480 X#  endif
2481 X
2482 X#  if defined (MOUNT_PORTAL)
2483 X                case MOUNT_PORTAL:
2484 X                {
2485 X                    strncpy (diskInfo [idx].fsType, "portal", DI_TYPE_LEN);
2486 X                    break;
2487 X                }
2488 X#  endif
2489 X
2490 X#  if defined (MOUNT_NULL)
2491 X                case MOUNT_NULL:
2492 X                {
2493 X                    strncpy (diskInfo [idx].fsType, "null", DI_TYPE_LEN);
2494 X                    break;
2495 X                }
2496 X#  endif
2497 X
2498 X#  if defined (MOUNT_UMAP)
2499 X                case MOUNT_UMAP:
2500 X                {
2501 X                    strncpy (diskInfo [idx].fsType, "umap", DI_TYPE_LEN);
2502 X                    break;
2503 X                }
2504 X#  endif
2505 X
2506 X#  if defined (MOUNT_KERNFS)
2507 X                case MOUNT_KERNFS:
2508 X                {
2509 X                    strncpy (diskInfo [idx].fsType, "kernfs", DI_TYPE_LEN);
2510 X                    break;
2511 X                }
2512 X#  endif
2513 X
2514 X#  if defined (MOUNT_PROCFS)
2515 X                case MOUNT_PROCFS:      /* proc filesystem */
2516 X                {
2517 X                    strncpy (diskInfo [idx].fsType, "pfs", DI_TYPE_LEN);
2518 X                    break;
2519 X                }
2520 X#  endif
2521 X
2522 X#  if defined (MOUNT_AFS)
2523 X                case MOUNT_AFS:
2524 X                {
2525 X                    strncpy (diskInfo [idx].fsType, "afs", DI_TYPE_LEN);
2526 X                    break;
2527 X                }
2528 X#  endif
2529 X
2530 X#  if defined (MOUNT_ISOFS)
2531 X                case MOUNT_ISOFS:       /* iso9660 cdrom */
2532 X                {
2533 X                    strncpy (diskInfo [idx].fsType, "iso9660fs", DI_TYPE_LEN);
2534 X                    break;
2535 X                }
2536 X#  endif
2537 X
2538 X#  if defined (MOUNT_ISO9660) && ! defined (MOUNT_CD9660)
2539 X                case MOUNT_ISO9660:       /* iso9660 cdrom */
2540 X                {
2541 X                    strncpy (diskInfo [idx].fsType, "iso9660", DI_TYPE_LEN);
2542 X                    break;
2543 X                }
2544 X#  endif
2545 X
2546 X#  if defined (MOUNT_CD9660)
2547 X                case MOUNT_CD9660:       /* iso9660 cdrom */
2548 X                {
2549 X                    strncpy (diskInfo [idx].fsType, "cd9660", DI_TYPE_LEN);
2550 X                    break;
2551 X                }
2552 X#  endif
2553 X
2554 X#  if defined (MOUNT_UNION)
2555 X                case MOUNT_UNION:
2556 X                {
2557 X                    strncpy (diskInfo [idx].fsType, "union", DI_TYPE_LEN);
2558 X                    break;
2559 X                }
2560 X#  endif
2561 X            } /* switch on mount type */
2562 X        }
2563 X# else
2564 X#  if defined (HAS_GETMNTINFO_FSTYPENAME)
2565 X        strncpy (diskInfo [idx].fsType, mntbufp [idx].f_fstypename, DI_TYPE_LEN);
2566 X#  else
2567 X            /* could use getvfsbytype here... */
2568 X        if ((fstype >= 0) && (fstype < MNT_NUMTYPES))
2569 X        {
2570 X            strncpy (diskInfo [idx].fsType, mnt_names [fstype], DI_TYPE_LEN);
2571 X        }
2572 X        else
2573 X        {
2574 X            sprintf (diskInfo [idx].fsType, DI_UNKNOWN_FSTYPE, fstype);
2575 X        }
2576 X#  endif
2577 X# endif /* has fs_types.h */
2578 X
2579 X#if defined (MNT_RDONLY)
2580 X        if ((mntbufp [idx].f_flags & MNT_RDONLY) == MNT_RDONLY)
2581 X        {
2582 X            strcat (diskInfo [idx].options, "ro,");
2583 X        }
2584 X        else
2585 X        {
2586 X            strcat (diskInfo [idx].options, "rw,");
2587 X        }
2588 X#endif
2589 X#if defined (MNT_SYNCHRONOUS)
2590 X        if ((mntbufp [idx].f_flags & MNT_SYNCHRONOUS) == MNT_SYNCHRONOUS)
2591 X        {
2592 X            strcat (diskInfo [idx].options, "sync,");
2593 X        }
2594 X#endif
2595 X#if defined (MNT_NOEXEC)
2596 X        if ((mntbufp [idx].f_flags & MNT_NOEXEC) == MNT_NOEXEC)
2597 X        {
2598 X            strcat (diskInfo [idx].options, "noexec,");
2599 X        }
2600 X#endif
2601 X#if defined (MNT_NOSUID)
2602 X        if ((mntbufp [idx].f_flags & MNT_NOSUID) != MNT_NOSUID)
2603 X        {
2604 X            strcat (diskInfo [idx].options, "suid,");
2605 X        }
2606 X#endif
2607 X#if defined (MNT_NODEV)
2608 X        if ((mntbufp [idx].f_flags & MNT_NODEV) == MNT_NODEV)
2609 X        {
2610 X            strcat (diskInfo [idx].options, "nodev,");
2611 X        }
2612 X#endif
2613 X#if defined (MNT_GRPID)
2614 X        if ((mntbufp [idx].f_flags & MNT_GRPID) == MNT_GRPID)
2615 X        {
2616 X            strcat (diskInfo [idx].options, "grpid,");
2617 X        }
2618 X#endif
2619 X#if defined (MNT_UNION)
2620 X        if ((mntbufp [idx].f_flags & MNT_UNION) == MNT_UNION)
2621 X        {
2622 X            strcat (diskInfo [idx].options, "union,");
2623 X        }
2624 X#endif
2625 X#if defined (MNT_ASYNC)
2626 X        if ((mntbufp [idx].f_flags & MNT_ASYNC) == MNT_ASYNC)
2627 X        {
2628 X            strcat (diskInfo [idx].options, "async,");
2629 X        }
2630 X#endif
2631 X#if defined (MNT_EXRDONLY)
2632 X        if ((mntbufp [idx].f_flags & MNT_EXRDONLY) == MNT_EXRDONLY)
2633 X        {
2634 X            strcat (diskInfo [idx].options, "exported ro,");
2635 X        }
2636 X#endif
2637 X#if defined (MNT_EXPORTED)
2638 X        if ((mntbufp [idx].f_flags & MNT_EXPORTED) == MNT_EXPORTED)
2639 X        {
2640 X            strcat (diskInfo [idx].options, "exported,");
2641 X        }
2642 X#endif
2643 X#if defined (MNT_EXRDMOSTLY)
2644 X        if ((mntbufp [idx].f_flags & MNT_EXRDMOSTLY) == MNT_EXRDMOSTLY)
2645 X        {
2646 X                /* what's read-mostly ? */
2647 X            strcat (diskInfo [idx].options, "exported read-mostly,");
2648 X        }
2649 X#endif
2650 X#if defined (MNT_DEFEXPORTED)
2651 X        if ((mntbufp [idx].f_flags & MNT_DEFEXPORTED) == MNT_DEFEXPORTED)
2652 X        {
2653 X                /* what's this ? */
2654 X            strcat (diskInfo [idx].options, "exported world,");
2655 X        }
2656 X#endif
2657 X#if defined (MNT_EXPORTANON)
2658 X        if ((mntbufp [idx].f_flags & MNT_EXPORTANON) == MNT_EXPORTANON)
2659 X        {
2660 X            strcat (diskInfo [idx].options, "exported anon,");
2661 X        }
2662 X#endif
2663 X#if defined (MNT_EXKERB)
2664 X        if ((mntbufp [idx].f_flags & MNT_EXKERB) == MNT_EXKERB)
2665 X        {
2666 X            strcat (diskInfo [idx].options, "exported kerberos,");
2667 X        }
2668 X#endif
2669 X#if defined (MNT_LOCAL)
2670 X        if ((mntbufp [idx].f_flags & MNT_LOCAL) == MNT_LOCAL)
2671 X        {
2672 X            strcat (diskInfo [idx].options, "local,");
2673 X        }
2674 X#endif
2675 X#if defined (MNT_QUOTA)
2676 X        if ((mntbufp [idx].f_flags & MNT_QUOTA) == MNT_QUOTA)
2677 X        {
2678 X            strcat (diskInfo [idx].options, "quota,");
2679 X        }
2680 X#endif
2681 X#if defined (MNT_ROOTFS)
2682 X        if ((mntbufp [idx].f_flags & MNT_ROOTFS) == MNT_ROOTFS)
2683 X        {
2684 X            strcat (diskInfo [idx].options, "root,");
2685 X        }
2686 X#endif
2687 X#if defined (MNT_USER)
2688 X        if ((mntbufp [idx].f_flags & MNT_USER) == MNT_USER)
2689 X        {
2690 X            strcat (diskInfo [idx].options, "user,");
2691 X        }
2692 X#endif
2693 X#if defined (MNT_SECURE)
2694 X        if ((mntbufp [idx].f_flags & MNT_SECURE) == MNT_SECURE)
2695 X        {
2696 X            strcat (diskInfo [idx].options, "secure,");
2697 X        }
2698 X#endif
2699 X
2700 X        len = strlen (diskInfo [idx].options);
2701 X        if (len > 0)
2702 X        {
2703 X            --len;
2704 X        }
2705 X        if (diskInfo [idx].options [len]==',')
2706 X        {
2707 X            diskInfo [idx].options [len] = '\0';
2708 X        }
2709 X
2710 X        if (debug > 1)
2711 X        {
2712 X            printf ("%s: %s\n", diskInfo [idx].name, diskInfo [idx].fsType);
2713 X            printf ("\tblocks: tot:%ld free:%ld avail:%ld\n",
2714 X                    mntbufp [idx].f_blocks, mntbufp [idx].f_bfree,
2715 X                    mntbufp [idx].f_bavail);
2716 X            printf ("\tmult: %f\n", mult);
2717 X# if defined (HAS_GETMNTINFO_FSIZE)
2718 X            printf ("\tfsize:%ld \n", mntbufp [idx].f_fsize);
2719 X            printf ("\tbsize:%ld \n", mntbufp [idx].f_bsize);
2720 X# endif
2721 X# if defined (HAS_GETMNTINFO_BSIZE)
2722 X            printf ("\tbsize:%ld \n", mntbufp [idx].f_bsize);
2723 X            printf ("\tiosize:%ld \n", mntbufp [idx].f_iosize);
2724 X# endif
2725 X            printf ("\tinodes: tot:%ld free:%ld\n",
2726 X                    mntbufp [idx].f_files, mntbufp [idx].f_ffree);
2727 X        }
2728 X    }
2729 X
2730 X    free ((char *) mntbufp);  /* man page says this can't be freed. */
2731 X                              /* is it ok to try?                   */
2732 X    return 0;
2733 X}
2734 X
2735 X/* this is a no-op; we have already done all the work */
2736 Xstatic void
2737 XgetDiskInfo ()
2738 X{
2739 X}
2740 X
2741 X#endif /* HAS_GETMNTINFO */
2742 X
2743 X#if defined (HAS_GETMNT)
2744 X
2745 X/*
2746 X * getDiskEntries
2747 X *
2748 X * ULTRIX does this with a system call.  The system call allows one
2749 X * to retrieve the information in a series of calls, but coding that
2750 X * looks a little tricky; I just allocate a huge buffer and do it in
2751 X * one shot.
2752 X *
2753 X *                  [mogul@wrl.dec.com (Jeffrey Mogul)]
2754 X */
2755 X
2756 Xstatic int
2757 XgetDiskEntries ()
2758 X{
2759 X    int             count;
2760 X    int             bufsize;
2761 X    int             idx;
2762 X    short           fstype;
2763 X    struct fs_data  *fsdbuf;
2764 X    int             start;
2765 X    int             len;
2766 X
2767 X
2768 X    bufsize = NMOUNT * sizeof (struct fs_data);  /* enough for max # mounts */
2769 X    fsdbuf = (struct fs_data *) malloc (bufsize);
2770 X    if (fsdbuf == (struct fs_data *) NULL)
2771 X    {
2772 X        fprintf (stderr, "malloc (%d) for getmnt () failed errno %d\n",
2773 X                 bufsize, errno);
2774 X        return -1;
2775 X    }
2776 X
2777 X    start = 0;
2778 X    count = getmnt (&start, fsdbuf, bufsize, STAT_MANY, 0);
2779 X    if (count < 1)
2780 X    {
2781 X        fprintf (stderr, "Unable to do getmnt () [= %d] errno %d\n",
2782 X                 count, errno);
2783 X        free ((char *) fsdbuf);
2784 X        return -1;
2785 X    }
2786 X
2787 X    diCount = count;
2788 X    diskInfo = (DiskInfo *) malloc (sizeof (DiskInfo) * count);
2789 X    if (diskInfo == (DiskInfo *) NULL)
2790 X    {
2791 X        fprintf (stderr, "malloc failed for diskInfo. errno %d\n", errno);
2792 X        free ((char *) fsdbuf);
2793 X        return -1;
2794 X    }
2795 X    memset ((char *) diskInfo, '\0', sizeof (DiskInfo) * count);
2796 X
2797 X    for (idx = 0; idx < count; idx++)
2798 X    {
2799 X        diskInfo [idx].printFlag = DI_OK;
2800 X        diskInfo [idx].isLocal = TRUE;
2801 X
2802 X        if ((fsdbuf [idx].fd_req.flags & M_LOCAL) != M_LOCAL)
2803 X        {
2804 X            diskInfo [idx].isLocal = FALSE;
2805 X        }
2806 X
2807 X        if (diskInfo [idx].isLocal == FALSE &&
2808 X                (flags & DI_F_LOCAL_ONLY) == DI_F_LOCAL_ONLY)
2809 X        {
2810 X            diskInfo [idx].printFlag = DI_IGNORE;
2811 X            if (debug > 2)
2812 X            {
2813 X                printf ("mnt: ignore: remote: %s\n",
2814 X                        diskInfo [idx].name);
2815 X            }
2816 X        }
2817 X
2818 X        strncpy (diskInfo [idx].special, fsdbuf [idx].fd_devname, DI_SPEC_NAME_LEN);
2819 X        strncpy (diskInfo [idx].name, fsdbuf [idx].fd_path, DI_NAME_LEN);
2820 X
2821 X            /* ULTRIX keeps these fields in units of 1K byte */
2822 X        diskInfo [idx].totalBlocks = fsdbuf [idx].fd_btot;
2823 X        diskInfo [idx].freeBlocks = fsdbuf [idx].fd_bfree;
2824 X        diskInfo [idx].availBlocks = (int) fsdbuf [idx].fd_bfreen;
2825 X
2826 X        diskInfo [idx].totalInodes = fsdbuf [idx].fd_gtot;
2827 X        diskInfo [idx].freeInodes = fsdbuf [idx].fd_gfree;
2828 X        diskInfo [idx].availInodes = fsdbuf [idx].fd_gfree;
2829 X
2830 X        fstype = fsdbuf [idx].fd_fstype;
2831 X        if (fstype == GT_UNKWN)
2832 X        {
2833 X            diskInfo [idx].printFlag = DI_IGNORE;
2834 X            if (debug > 2)
2835 X            {
2836 X                printf ("mnt: ignore: disk type unknown: %s\n",
2837 X                        diskInfo [idx].name);
2838 X            }
2839 X        }
2840 X        else if ((fstype > 0) && (fstype < GT_NUMTYPES))
2841 X        {
2842 X            strncpy (diskInfo [idx].fsType, gt_names [fstype], DI_TYPE_LEN);
2843 X        }
2844 X        else
2845 X        {
2846 X            sprintf (diskInfo [idx].fsType, "Unknown fstyp %.2d", fstype);
2847 X        }
2848 X
2849 X        if ((fsdbuf [idx].fd_req.flags & M_RONLY) == M_RONLY)
2850 X        {
2851 X            strcat (diskInfo [idx].options, "ro,");
2852 X        }
2853 X        else
2854 X        {
2855 X            strcat (diskInfo [idx].options, "rw,");
2856 X        }
2857 X        if ((fsdbuf [idx].fd_req.flags & M_NOSUID) != M_NOSUID)
2858 X        {
2859 X            strcat (diskInfo [idx].options, "suid,");
2860 X        }
2861 X        if ((fsdbuf [idx].fd_req.flags & M_QUOTA) == M_QUOTA)
2862 X        {
2863 X            strcat (diskInfo [idx].options, "quota,");
2864 X        }
2865 X        if ((fsdbuf [idx].fd_req.flags & M_LOCAL) != M_LOCAL)
2866 X        {
2867 X            strcat (diskInfo [idx].options, "remote,");
2868 X        }
2869 X        if ((fsdbuf [idx].fd_req.flags & M_NODEV) == M_NODEV)
2870 X        {
2871 X            strcat (diskInfo [idx].options, "nodev,");
2872 X        }
2873 X        if ((fsdbuf [idx].fd_req.flags & M_FORCE) == M_FORCE)
2874 X        {
2875 X            strcat (diskInfo [idx].options, "force,");
2876 X        }
2877 X        if ((fsdbuf [idx].fd_req.flags & M_SYNC) == M_SYNC)
2878 X        {
2879 X            strcat (diskInfo [idx].options, "sync,");
2880 X        }
2881 X        if ((fsdbuf [idx].fd_req.flags & M_NOCACHE) == M_NOCACHE)
2882 X        {
2883 X            strcat (diskInfo [idx].options, "nocache,");
2884 X        }
2885 X        if ((fsdbuf [idx].fd_req.flags & M_EXPORTED) == M_EXPORTED)
2886 X        {
2887 X            strcat (diskInfo [idx].options, "exported," );
2888 X        }
2889 X        if ((fsdbuf [idx].fd_req.flags & M_EXRONLY) == M_EXRONLY)
2890 X        {
2891 X            strcat (diskInfo [idx].options, "exported ro,");
2892 X        }
2893 X        if ((fsdbuf [idx].fd_req.flags & M_NOEXEC) == M_NOEXEC)
2894 X        {
2895 X            strcat (diskInfo [idx].options, "noexec,");
2896 X        }
2897 X
2898 X        len = strlen (diskInfo [idx].options);
2899 X        if (len > 0)
2900 X        {
2901 X            --len;
2902 X        }
2903 X        if (diskInfo [idx].options [len]==',')
2904 X        {
2905 X            diskInfo [idx].options [len] = '\0';
2906 X        }
2907 X
2908 X        if (debug > 1)
2909 X        {
2910 X            printf ("%s: %s\n", diskInfo [idx].name, diskInfo [idx].fsType);
2911 X            printf ("\tblocks: tot:%ld free:%ld avail:%ld\n",
2912 X                    fsdbuf [idx].fd_btot, fsdbuf [idx].fd_bfree,
2913 X                    (int) fsdbuf [idx].fd_bfreen);
2914 X            printf ("\tinodes: tot:%ld free:%ld\n",
2915 X                    fsdbuf [idx].fd_gtot, fsdbuf [idx].fd_gfree);
2916 X        }
2917 X    }
2918 X
2919 X    free ((char *) fsdbuf);
2920 X    return 0;
2921 X}
2922 X
2923 X/* this is a no-op; we have already done all the work */
2924 Xstatic void
2925 XgetDiskInfo ()
2926 X{
2927 X}
2928 X
2929 X#endif /* HAS_GETMNT */
2930 X
2931 X
2932 X#if defined (HAS_MNTCTL)
2933 X
2934 X/*
2935 X * getDiskEntries
2936 X *
2937 X * AIX V3.2 uses mntctl to find out about mounted file systems
2938 X *
2939 X */
2940 X
2941 X# define NUM_AIX_FSTYPES         6
2942 Xstatic char *AIX_fsType [NUM_AIX_FSTYPES] =
2943 X    { "oaix", "", "nfs", "jfs", "", "cdrom" };
2944 X
2945 X/*
2946 X * from xfsm-1.80:
2947 X *
2948 X * MNT_AIX - "aix"
2949 X * MNT_NFS - "nfs"
2950 X * MNT_JFS - "jfs"
2951 X * MNT_CDROM - "cdrom"
2952 X * other - "user defined"
2953 X *
2954 X */
2955 X
2956 Xstatic int
2957 XgetDiskEntries ()
2958 X{
2959 X    int             num;        /* number of vmount structs returned    */
2960 X    char            *vmbuf;     /* buffer for vmount structs returned   */
2961 X    int             vmbufsz;    /* size in bytes of vmbuf               */
2962 X    int             i;          /* index for looping and stuff          */
2963 X    char            *bufp;      /* pointer into vmbuf                   */
2964 X    struct vmount   *vmtp;      /* pointer into vmbuf                   */
2965 X    struct vfs_ent  *ve;        /* pointer for file system type entry   */
2966 X    int             len;
2967 X
2968 X
2969 X    i = 0;
2970 X    vmbufsz = sizeof (struct vmount) * DI_FSMAGIC; /* initial vmount buffer */
2971 X
2972 X    do
2973 X    {
2974 X        if ((vmbuf = (char *) malloc (vmbufsz)) == (char *) NULL)
2975 X        {
2976 X            fprintf (stderr, "malloc (%d) for mntctl() failed errno %d\n",
2977 X                    vmbufsz, errno);
2978 X            return -1;
2979 X        }
2980 X
2981 X        num = mntctl (MCTL_QUERY, vmbufsz, vmbuf);
2982 X            /*
2983 X             * vmbuf is too small, could happen for
2984 X             * following reasons:
2985 X             * - inital buffer is too small
2986 X             * - newly mounted file system
2987 X             */
2988 X        if (num == 0)
2989 X        {
2990 X            memcpy (&vmbufsz, vmbuf, sizeof (vmbufsz)); /* see mntctl(2) */
2991 X            if (debug > 0)
2992 X            {
2993 X                printf ("vmbufsz too small, new size: %d\n", vmbufsz);
2994 X            }
2995 X            free ((char *) vmbuf); /* free this last, it's still being used! */
2996 X            ++i;
2997 X        }
2998 X    } while (num == 0 && i < DI_RETRY_COUNT);
2999 X
3000 X    if (i >= DI_RETRY_COUNT)
3001 X    {
3002 X        free ((char *) vmbuf);
3003 X        fprintf (stderr, "unable to allocate adequate buffer for mntctl\n");
3004 X        return -1;
3005 X    }
3006 X
3007 X    switch (num)
3008 X    {
3009 X            /* error happened, probably null vmbuf */
3010 X        case -1:
3011 X        {
3012 X            free ((char *) vmbuf);
3013 X            fprintf (stderr,"%s errno %d\n", strerror (errno), errno);
3014 X            return -1;
3015 X        }
3016 X
3017 X            /* 'num' vmount structs returned in vmbuf */
3018 X        default:
3019 X        {
3020 X            diCount = num;
3021 X            diskInfo = (DiskInfo *) calloc (sizeof (DiskInfo), diCount);
3022 X            if (diskInfo == (DiskInfo *) NULL)
3023 X            {
3024 X                fprintf (stderr, "malloc failed for diskInfo. errno %d\n", errno);
3025 X                return -1;
3026 X            }
3027 X
3028 X            bufp = vmbuf;
3029 X            for (i = 0; i < num; i++)
3030 X            {
3031 X                vmtp = (struct vmount *) bufp;
3032 X                diskInfo [i].printFlag = DI_OK;
3033 X                diskInfo [i].isLocal = TRUE;
3034 X
3035 X                strncpy (diskInfo [i].special,
3036 X                        (char *) vmt2dataptr (vmtp, VMT_OBJECT),
3037 X                        DI_SPEC_NAME_LEN);
3038 X                strncpy (diskInfo [i].name,
3039 X                        (char *) vmt2dataptr (vmtp, VMT_STUB), DI_NAME_LEN);
3040 X
3041 X                ve = getvfsbytype (vmtp->vmt_gfstype);
3042 X                if (ve == (struct vfs_ent *) NULL || *ve->vfsent_name == '\0')
3043 X                {
3044 X                    if (vmtp->vmt_gfstype >= 0 &&
3045 X                            (vmtp->vmt_gfstype < NUM_AIX_FSTYPES))
3046 X                    {
3047 X                        strncpy (diskInfo [i].fsType,
3048 X                                AIX_fsType [vmtp->vmt_gfstype], DI_TYPE_LEN);
3049 X                    }
3050 X                }
3051 X                else
3052 X                {
3053 X                    strncpy (diskInfo [i].fsType, ve->vfsent_name, DI_TYPE_LEN);
3054 X                }
3055 X
3056 X                if ((vmtp->vmt_flags & MNT_READONLY) == MNT_READONLY)
3057 X                {
3058 X                    strcat (diskInfo [i].options, "ro,");
3059 X                }
3060 X                else
3061 X                {
3062 X                    strcat (diskInfo [i].options, "rw,");
3063 X                }
3064 X                if ((vmtp->vmt_flags & MNT_NOSUID) != MNT_NOSUID)
3065 X                {
3066 X                    strcat (diskInfo [i].options, "suid,");
3067 X                }
3068 X                if ((vmtp->vmt_flags & MNT_REMOVABLE) == MNT_REMOVABLE)
3069 X                {
3070 X                    strcat (diskInfo [i].options, "removable,");
3071 X                }
3072 X                if ((vmtp->vmt_flags & MNT_DEVICE) == MNT_DEVICE)
3073 X                {
3074 X                    strcat (diskInfo [i].options, "device,");
3075 X                }
3076 X                if ((vmtp->vmt_flags & MNT_REMOTE) == MNT_REMOTE)
3077 X                {
3078 X                    strcat (diskInfo [i].options, "remote,");
3079 X                    diskInfo [i].isLocal = FALSE;
3080 X                }
3081 X                if ((vmtp->vmt_flags & MNT_UNMOUNTING) == MNT_UNMOUNTING)
3082 X                {
3083 X                    strcat (diskInfo [i].options, "unmounting,");
3084 X                }
3085 X                if ((vmtp->vmt_flags & MNT_SYSV_MOUNT) == MNT_SYSV_MOUNT)
3086 X                {
3087 X                    strcat (diskInfo [i].options, "sysv mount,");
3088 X                }
3089 X                if ((vmtp->vmt_flags & MNT_NODEV) == MNT_NODEV)
3090 X                {
3091 X                    strcat (diskInfo [i].options, "nodev,");
3092 X                }
3093 X
3094 X                    /* remove trailing comma */
3095 X                len = strlen (diskInfo [i].options);
3096 X                if (len > 0)
3097 X                {
3098 X                    --len;
3099 X                }
3100 X                if (diskInfo [i].options [len] == ',')
3101 X                {
3102 X                    diskInfo [i].options [len] = '\0';
3103 X                }
3104 X
3105 X                strncpy (diskInfo [i].mountTime, ctime (&vmtp->vmt_time),
3106 X                        DI_MNT_TIME_LEN);
3107 X
3108 X                if (diskInfo [i].isLocal == FALSE &&
3109 X                        (flags & DI_F_LOCAL_ONLY) == DI_F_LOCAL_ONLY)
3110 X                {
3111 X                    diskInfo [i].printFlag = DI_IGNORE;
3112 X                    if (debug > 2)
3113 X                    {
3114 X                        printf ("mnt: ignore: remote: %s\n",
3115 X                                diskInfo [i].name);
3116 X                    }
3117 X                }
3118 X
3119 X                bufp += vmtp->vmt_length;
3120 X            }
3121 X
3122 X            if (debug > 0)
3123 X            {
3124 X                printf ("mnt:%s - %s : %s\n", diskInfo [i].name,
3125 X                        diskInfo [i].special, diskInfo [i].fsType);
3126 X                printf ("\t%s\n", (char *) vmt2dataptr (vmtp, VMT_ARGS));
3127 X            }
3128 X
3129 X            break;
3130 X        } /* valid value returned */
3131 X    } /* switch on num */
3132 X}
3133 X
3134 X#endif  /* HAS_MNTCTL */
3135 X
3136 X
3137 X#if defined (HAS_STATVFS)
3138 X
3139 X/*
3140 X * getDiskInfo
3141 X *
3142 X * SysV.4.  statvfs () returns both the free and available blocks.
3143 X *
3144 X */
3145 X
3146 Xstatic void
3147 XgetDiskInfo ()
3148 X{
3149 X    int             i;
3150 X    double          mult;
3151 X    struct statvfs  statBuf;
3152 X
3153 X    for (i = 0; i < diCount; ++i)
3154 X    {
3155 X        if (diskInfo [i].isLocal == FALSE &&
3156 X                (flags & DI_F_LOCAL_ONLY) == DI_F_LOCAL_ONLY)
3157 X        {
3158 X            diskInfo [i].printFlag = DI_IGNORE;
3159 X            if (debug > 2)
3160 X            {
3161 X                printf ("mnt: ignore: remote: %s\n",
3162 X                        diskInfo [i].name);
3163 X            }
3164 X        }
3165 X
3166 X        if (diskInfo [i].printFlag == DI_OK || (flags & DI_F_ALL) == DI_F_ALL)
3167 X        {
3168 X            if (statvfs (diskInfo [i].name, &statBuf) == 0)
3169 X            {
3170 X                    /* data general DG/UX 5.4R3.00 sometime returns 0   */
3171 X                    /* in the fragment size field.                      */
3172 X                if (statBuf.f_frsize == 0 && statBuf.f_bsize != 0)
3173 X                {
3174 X                    mult = (double) (long) statBuf.f_bsize / dispBlockSize;
3175 X                }
3176 X                else
3177 X                {
3178 X                    mult = (double) (long) statBuf.f_frsize / dispBlockSize;
3179 X                }
3180 X
3181 X                diskInfo [i].totalBlocks = ((double) (_s_fs_size_t) statBuf.f_blocks * mult);
3182 X                diskInfo [i].freeBlocks = ((double) (_s_fs_size_t) statBuf.f_bfree * mult);
3183 X                diskInfo [i].availBlocks = ((double) (_s_fs_size_t) statBuf.f_bavail * mult);
3184 X
3185 X                diskInfo [i].totalInodes = statBuf.f_files;
3186 X                diskInfo [i].freeInodes = statBuf.f_ffree;
3187 X                diskInfo [i].availInodes = statBuf.f_favail;
3188 X
3189 X#if defined (HAS_STATVFS_BASETYPE)
3190 X                strncpy (diskInfo [i].fsType, statBuf.f_basetype, DI_TYPE_LEN);
3191 X#endif
3192 X
3193 X                if (debug > 1)
3194 X                {
3195 X                    printf ("%s: %s\n", diskInfo [i].name, diskInfo [i].fsType);
3196 X                    printf ("\tmult:%f\n", mult);
3197 X                    printf ("\tbsize:%ld  frsize:%ld\n", statBuf.f_bsize,
3198 X                            statBuf.f_frsize);
3199 X#if defined (HAS_64BIT_STATFS_FLDS)
3200 X                    printf ("\tblocks: tot:%llu free:%lld avail:%llu\n",
3201 X                            statBuf.f_blocks, statBuf.f_bfree, statBuf.f_bavail);
3202 X                    printf ("\tinodes: tot:%llu free:%lld avail:%llu\n",
3203 X                            statBuf.f_files, statBuf.f_ffree, statBuf.f_favail);
3204 X#else
3205 X                    printf ("\tblocks: tot:%lu free:%ld avail:%lu\n",
3206 X                            statBuf.f_blocks, statBuf.f_bfree, statBuf.f_bavail);
3207 X                    printf ("\tinodes: tot:%lu free:%ld avail:%lu\n",
3208 X                            statBuf.f_files, statBuf.f_ffree, statBuf.f_favail);
3209 X#endif
3210 X                }
3211 X            }
3212 X            else
3213 X            {
3214 X                fprintf (stderr, "statvfs: %s ", diskInfo [i].name);
3215 X                perror ("");
3216 X            }
3217 X        }
3218 X    } /* for each entry */
3219 X}
3220 X
3221 X#endif /* HAS_STATVFS */
3222 X
3223 X
3224 X#if defined (HAS_STATFS_BSD) && ! defined (HAS_STATVFS) && \
3225 X        ! defined (HAS_GETMNTINFO) && ! defined (HAS_GETMNT)
3226 X
3227 X/*
3228 X * getDiskInfo
3229 X *
3230 X * SunOS/BSD/Pyramid
3231 X *
3232 X */
3233 X
3234 Xstatic void
3235 XgetDiskInfo ()
3236 X{
3237 X    int             i;
3238 X    double          mult;
3239 X    struct statfs   statBuf;
3240 X
3241 X    for (i = 0; i < diCount; ++i)
3242 X    {
3243 X        if (diskInfo [i].printFlag == DI_OK || (flags & DI_F_ALL) == DI_F_ALL)
3244 X        {
3245 X            if (statfs (diskInfo [i].name, &statBuf) == 0)
3246 X            {
3247 X                mult = (double) statBuf.f_bsize / dispBlockSize;
3248 X                diskInfo [i].totalBlocks = ((double) (_s_fs_size_t) statBuf.f_blocks * mult);
3249 X                diskInfo [i].freeBlocks = ((double) (_s_fs_size_t) statBuf.f_bfree * mult);
3250 X                diskInfo [i].availBlocks = ((double) (_s_fs_size_t) statBuf.f_bavail * mult);
3251 X
3252 X                diskInfo [i].totalInodes = statBuf.f_files;
3253 X                diskInfo [i].freeInodes = statBuf.f_ffree;
3254 X                diskInfo [i].availInodes = statBuf.f_ffree;
3255 X# if defined (HAS_SYSFS)
3256 X                sysfs (GETFSTYP, statBuf.f_fstyp, diskInfo [i].fsType);
3257 X# endif
3258 X
3259 X                if (debug > 1)
3260 X                {
3261 X                    printf ("%s: %s\n", diskInfo [i].name, diskInfo [i].fsType);
3262 X                    printf ("\tmult:%f\n", mult);
3263 X                    printf ("\tbsize:%ld\n", statBuf.f_bsize);
3264 X                    printf ("\tblocks: tot:%ld free:%ld avail:%ld\n",
3265 X                            statBuf.f_blocks, statBuf.f_bfree, statBuf.f_bavail);
3266 X                    printf ("\tinodes: tot:%ld free:%ld\n",
3267 X                            statBuf.f_files, statBuf.f_ffree);
3268 X                }
3269 X            } /* if we got the info */
3270 X            else
3271 X            {
3272 X                fprintf (stderr, "statfs: %s ", diskInfo [i].name);
3273 X                perror ("");
3274 X            }
3275 X        }
3276 X    } /* for each entry */
3277 X}
3278 X
3279 X#endif /* HAS_STATFS_BSD */
3280 X
3281 X#if defined (HAS_STATFS_SYSV3) && ! defined (HAS_STATVFS) && \
3282 X        ! defined (HAS_GETMNTINFO) && ! defined (HAS_GETMNT)
3283 X
3284 X/*
3285 X * getDiskInfo
3286 X *
3287 X * SysV.3.  We don't have available blocks; just set it to free blocks.
3288 X * The sysfs () call is used to get the disk type name.
3289 X *
3290 X */
3291 X
3292 Xstatic void
3293 XgetDiskInfo ()
3294 X{
3295 X    int             i;
3296 X    double          mult;
3297 X    struct statfs   statBuf;
3298 X
3299 X    for (i = 0; i < diCount; ++i)
3300 X    {
3301 X        if (diskInfo [i].printFlag == DI_OK || (flags & DI_F_ALL) == DI_F_ALL)
3302 X        {
3303 X            if (statfs (diskInfo [i].name, &statBuf, sizeof (statBuf), 0) == 0)
3304 X            {
3305 X# if defined (HAS_STATFS_FRSIZE)
3306 X                if (statBuf.f_frsize == 0 && statBuf.f_bsize != 0)
3307 X                {
3308 X                    mult = (double) (long) statBuf.f_bsize / dispBlockSize;
3309 X                }
3310 X                else
3311 X                {
3312 X                    mult = (double) (long) statBuf.f_frsize / dispBlockSize;
3313 X                }
3314 X# else
3315 X                mult = (double) UBSIZE / dispBlockSize;
3316 X# endif
3317 X                diskInfo [i].totalBlocks = ((double) (_s_fs_size_t) statBuf.f_blocks * mult);
3318 X                diskInfo [i].freeBlocks = ((double) (_s_fs_size_t) statBuf.f_bfree * mult);
3319 X                diskInfo [i].availBlocks = ((double) (_s_fs_size_t) statBuf.f_bfree * mult);
3320 X
3321 X                diskInfo [i].totalInodes = statBuf.f_files;
3322 X                diskInfo [i].freeInodes = statBuf.f_ffree;
3323 X                diskInfo [i].availInodes = statBuf.f_ffree;
3324 X# if defined (HAS_SYSFS)
3325 X                sysfs (GETFSTYP, statBuf.f_fstyp, diskInfo [i].fsType);
3326 X# endif
3327 X
3328 X                if (debug > 1)
3329 X                {
3330 X                    printf ("%s: %s\n", diskInfo [i].name, diskInfo [i].fsType);
3331 X                    printf ("\tmult:%f\n", mult);
3332 X# if defined (HAS_STATFS_FRSIZE)
3333 X                    printf ("\tbsize:%ld\n", statBuf.f_bsize);
3334 X                    printf ("\tfrsize:%ld\n", statBuf.f_frsize);
3335 X# else
3336 X                    printf ("\tUBSIZE:%ld\n", UBSIZE);
3337 X# endif
3338 X                    printf ("\tblocks: tot:%ld free:%ld\n",
3339 X                            statBuf.f_blocks, statBuf.f_bfree);
3340 X                    printf ("\tinodes: tot:%ld free:%ld\n",
3341 X                            statBuf.f_files, statBuf.f_ffree);
3342 X                }
3343 X            } /* if we got the info */
3344 X            else
3345 X            {
3346 X                fprintf (stderr, "statfs: %s ", diskInfo [i].name);
3347 X                perror ("");
3348 X            }
3349 X        }
3350 X    } /* for each entry */
3351 X}
3352 X
3353 X#endif /* HAS_STATFS_SYSV3 */
3354 X
3355 X
3356 X#if defined (HAS_GETDISKFREESPACE)
3357 X
3358 X/*
3359 X * getDiskInfo
3360 X *
3361 X * Windows
3362 X *
3363 X */
3364 X
3365 X# define NUM_MSDOS_FSTYPES          7
3366 Xstatic char *MSDOS_diskType [NUM_MSDOS_FSTYPES] =
3367 X    { "unknown", "", "removable", "fixed", "remote", "cdrom", "ramdisk" };
3368 X# define MSDOS_BUFFER_SIZE          128
3369 X# define BYTES_PER_LOGICAL_DRIVE    4
3370 X
3371 Xstatic int
3372 XgetDiskEntries ()
3373 X{
3374 X    int             i;
3375 X    int             diskflag;
3376 X    int             rc;
3377 X    char            *p;
3378 X    char            buff [MSDOS_BUFFER_SIZE];
3379 X
3380 X
3381 X    diskflag = DI_IGNORE;
3382 X    rc = GetLogicalDriveStrings (MSDOS_BUFFER_SIZE, buff);
3383 X    diCount = rc / BYTES_PER_LOGICAL_DRIVE;
3384 X
3385 X    diskInfo = (DiskInfo *) calloc (sizeof (DiskInfo), diCount);
3386 X    if (diskInfo == (DiskInfo *) NULL)
3387 X    {
3388 X        fprintf (stderr, "malloc failed for diskInfo. errno %d\n", errno);
3389 X        return -1;
3390 X    }
3391 X
3392 X    for (i = 0; i < diCount; ++i)
3393 X    {
3394 X        p = buff + (BYTES_PER_LOGICAL_DRIVE * i);
3395 X        strncpy (diskInfo [i].name, p, DI_NAME_LEN);
3396 X        rc = GetDriveType (p);
3397 X        diskInfo [i].printFlag = DI_OK;
3398 X
3399 X        if (rc == DRIVE_NO_ROOT_DIR)
3400 X        {
3401 X            diskInfo [i].printFlag = DI_BAD;
3402 X        }
3403 X
3404 X            /* assume that any removable drives before the  */
3405 X            /* first non-removable disk are floppies...     */
3406 X        else if (rc == DRIVE_REMOVABLE)
3407 X        {
3408 X            diskInfo [i].printFlag = diskflag;
3409 X        }
3410 X        else
3411 X        {
3412 X            diskflag = DI_OK;
3413 X        }
3414 X
3415 X        if (rc != DRIVE_REMOTE)
3416 X        {
3417 X            diskInfo [i].isLocal = TRUE;
3418 X        }
3419 X        /* strncpy (diskInfo [i].fsType, MSDOS_diskType [rc], DI_TYPE_LEN); */
3420 X    } /* for each mounted drive */
3421 X
3422 X    return diCount;
3423 X}
3424 X
3425 X/*
3426 X * getDiskInfo
3427 X *
3428 X * Windows
3429 X *
3430 X */
3431 X
3432 Xstatic void
3433 XgetDiskInfo ()
3434 X{
3435 X    int                 i;
3436 X    int                 rc;
3437 X    double              mult;
3438 X    unsigned long       sectorspercluster;
3439 X    unsigned long       bytespersector;
3440 X    unsigned long       totalclusters;
3441 X    unsigned long       freeclusters;
3442 X    char                tbuff [MSDOS_BUFFER_SIZE];
3443 X    char                volName [MSDOS_BUFFER_SIZE];
3444 X    char                fsName [MSDOS_BUFFER_SIZE];
3445 X    DWORD               serialNo;
3446 X    DWORD               maxCompLen;
3447 X    DWORD               fsFlags;
3448 X
3449 X
3450 X    for (i = 0; i < diCount; ++i)
3451 X    {
3452 X        if (diskInfo [i].isLocal == FALSE &&
3453 X                (flags & DI_F_LOCAL_ONLY) == DI_F_LOCAL_ONLY)
3454 X        {
3455 X            diskInfo [i].printFlag = DI_IGNORE;
3456 X            if (debug > 2)
3457 X            {
3458 X                printf ("mnt: ignore: remote: %s\n",
3459 X                        diskInfo [i].name);
3460 X            }
3461 X        }
3462 X
3463 X        if (diskInfo [i].printFlag == DI_OK || (flags & DI_F_ALL) == DI_F_ALL)
3464 X        {
3465 X            rc = GetVolumeInformation (diskInfo [i].name,
3466 X                    volName, MSDOS_BUFFER_SIZE, &serialNo, &maxCompLen,
3467 X                    &fsFlags, fsName, MSDOS_BUFFER_SIZE);
3468 X            /* strcpy (tbuff, diskInfo [i].fsType); */
3469 X            /* strcat (tbuff, " "); */
3470 X            strncpy (diskInfo [i].fsType, fsName, DI_TYPE_LEN);
3471 X            strncpy (diskInfo [i].special, volName, DI_SPEC_NAME_LEN);
3472 X
3473 X            rc = GetDiskFreeSpace (diskInfo [i].name,
3474 X                    (LPDWORD) &sectorspercluster, (LPDWORD) &bytespersector,
3475 X                    (LPDWORD) &freeclusters, (LPDWORD) &totalclusters);
3476 X
3477 X            if (rc > 0)
3478 X            {
3479 X                mult = (double) (sectorspercluster *
3480 X                        bytespersector) / dispBlockSize;
3481 X                diskInfo [i].totalBlocks = ((double) (_s_fs_size_t) totalclusters * mult);
3482 X                diskInfo [i].freeBlocks = ((double) (_s_fs_size_t) freeclusters * mult);
3483 X                diskInfo [i].availBlocks = ((double) (_s_fs_size_t) freeclusters * mult);
3484 X
3485 X                diskInfo [i].totalInodes = 0;
3486 X                diskInfo [i].freeInodes = 0;
3487 X                diskInfo [i].availInodes = 0;
3488 X
3489 X                if (debug > 1)
3490 X                {
3491 X                    printf ("%s: %s\n", diskInfo [i].name, diskInfo [i].fsType);
3492 X                    printf ("\ts/c:%ld  b/s:%ld\n", sectorspercluster,
3493 X                        bytespersector);
3494 X                    printf ("\tmult:%f\n", mult);
3495 X                    printf ("\tclusters: tot:%ld free:%ld\n",
3496 X                        totalclusters, freeclusters);
3497 X                }
3498 X            }
3499 X            else
3500 X            {
3501 X                diskInfo [i].printFlag = DI_BAD;
3502 X                if (debug)
3503 X                {
3504 X                    printf ("disk %s; could not get disk space\n",
3505 X                            diskInfo [i].name);
3506 X                }
3507 X            }
3508 X        } /* if printable drive */
3509 X    } /* for each mounted drive */
3510 X}
3511 X
3512 X#endif /* HAS_GETDISKFREESPACE */
3513 END_OF_FILE
3514 if test 97566 -ne `wc -c <'di.c'`; then
3515     echo shar: \"'di.c'\" unpacked with wrong size!
3516 fi
3517 # end of 'di.c'
3518 fi
3519 echo shar: End of archive 2 \(of 3\).
3520 cp /dev/null ark2isdone
3521 MISSING=""
3522 for I in 1 2 3 ; do
3523     if test ! -f ark${I}isdone ; then
3524         MISSING="${MISSING} ${I}"
3525     fi
3526 done
3527 if test "${MISSING}" = "" ; then
3528     echo You have unpacked all 3 archives.
3529     rm -f ark[1-9]isdone
3530 else
3531     echo You still need to unpack the following archives:
3532     echo "        " ${MISSING}
3533 fi
3534 ##  End of shell archive.
3535 exit 0
3536
This page took 0.310329 seconds and 3 git commands to generate.