home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / bin / df / df.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-04  |  7.7 KB  |  299 lines

  1. /*
  2.  * Copyright (c) 1980, 1990 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. char copyright[] =
  36. "@(#) Copyright (c) 1980, 1990 The Regents of the University of California.\n\
  37.  All rights reserved.\n";
  38. #endif /* not lint */
  39.  
  40. #ifndef lint
  41. static char sccsid[] = "@(#)df.c    5.24 (Berkeley) 3/6/91";
  42. #endif /* not lint */
  43.  
  44. /*
  45.  * df
  46.  */
  47. #include <sys/param.h>
  48. #include <sys/stat.h>
  49. #include <sys/mount.h>
  50. #include <fcntl.h>
  51. #include <stdio.h>
  52. #include <stdlib.h>
  53. #include <string.h>
  54. #include <unistd.h>
  55.  
  56. char    *getmntpt();
  57. void    ufs_df(), prtstat();
  58. int    iflag, kflag, nflag;
  59. struct    ufs_args mdev;
  60.  
  61. int
  62. main(argc, argv)
  63.     int argc;
  64.     char **argv;
  65. {
  66.     extern int errno, optind;
  67.     int err, ch, i;
  68.     long width, maxwidth, mntsize;
  69.     char *mntpt, *mktemp();
  70.     struct stat stbuf;
  71.     struct statfs statfsbuf, *mntbuf;
  72.  
  73.     while ((ch = getopt(argc, argv, "ikn")) != EOF)
  74.         switch(ch) {
  75.         case 'i':
  76.             iflag = 1;
  77.             break;
  78.         case 'k':
  79.             kflag = 1;
  80.             break;
  81.         case 'n':
  82.             nflag = 1;
  83.             break;
  84.         case '?':
  85.         default:
  86.             fprintf(stderr,
  87.                 "usage: df [-ikn] [file | file_system ...]\n");
  88.             exit(1);
  89.         }
  90.     argc -= optind;
  91.     argv += optind;
  92.  
  93.     mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
  94.     maxwidth = 0;
  95.     for (i = 0; i < mntsize; i++) {
  96.         width = strlen(mntbuf[i].f_mntfromname);
  97.         if (width > maxwidth)
  98.             maxwidth = width;
  99.     }
  100.     if (!*argv) {
  101.         mntsize = getmntinfo(&mntbuf, (nflag ? MNT_NOWAIT : MNT_WAIT));
  102.         for (i = 0; i < mntsize; i++)
  103.             prtstat(&mntbuf[i], maxwidth);
  104.         exit(0);
  105.     }
  106.     for (; *argv; argv++) {
  107.         if (stat(*argv, &stbuf) < 0) {
  108.             err = errno;
  109.             if ((mntpt = getmntpt(*argv)) == 0) {
  110.                 fprintf(stderr, "df: %s: %s\n", *argv,
  111.                     strerror(err));
  112.                 continue;
  113.             }
  114.         } else if ((stbuf.st_mode & S_IFMT) == S_IFCHR) {
  115.             ufs_df(*argv, maxwidth);
  116.             continue;
  117.         } else if ((stbuf.st_mode & S_IFMT) == S_IFBLK) {
  118.             if ((mntpt = getmntpt(*argv)) == 0) {
  119.                 mntpt = mktemp(strdup("/tmp/df.XXXXXX"));
  120.                 mdev.fspec = *argv;
  121.                 if (mkdir(mntpt, DEFFILEMODE) != 0) {
  122.                     fprintf(stderr, "df: %s: %s\n",
  123.                         mntpt, strerror(errno));
  124.                     continue;
  125.                 }
  126.                 if (mount(MOUNT_UFS, mntpt, MNT_RDONLY,
  127.                     &mdev) != 0) {
  128.                     ufs_df(*argv, maxwidth);
  129.                     (void)rmdir(mntpt);
  130.                     continue;
  131.                 } else if (statfs(mntpt, &statfsbuf)) {
  132.                     statfsbuf.f_mntonname[0] = '\0';
  133.                     prtstat(&statfsbuf, maxwidth);
  134.                 } else
  135.                     fprintf(stderr, "df: %s: %s\n",
  136.                         *argv, strerror(errno));
  137.                 (void)unmount(mntpt, MNT_NOFORCE);
  138.                 (void)rmdir(mntpt);
  139.                 continue;
  140.             }
  141.         } else
  142.             mntpt = *argv;
  143.         /*
  144.          * Statfs does not take a `wait' flag, so we cannot
  145.          * implement nflag here.
  146.          */
  147.         if (statfs(mntpt, &statfsbuf) < 0) {
  148.             fprintf(stderr,
  149.                 "df: %s: %s\n", mntpt, strerror(errno));
  150.             continue;
  151.         }
  152.         if (argc == 1)
  153.             maxwidth = strlen(statfsbuf.f_mntfromname) + 1;
  154.         prtstat(&statfsbuf, maxwidth);
  155.     }
  156.     return (0);
  157. }
  158.  
  159. char *
  160. getmntpt(name)
  161.     char *name;
  162. {
  163.     long mntsize, i;
  164.     struct statfs *mntbuf;
  165.  
  166.     mntsize = getmntinfo(&mntbuf, (nflag ? MNT_NOWAIT : MNT_WAIT));
  167.     for (i = 0; i < mntsize; i++) {
  168.         if (!strcmp(mntbuf[i].f_mntfromname, name))
  169.             return (mntbuf[i].f_mntonname);
  170.     }
  171.     return (0);
  172. }
  173.  
  174. /*
  175.  * Print out status about a filesystem.
  176.  */
  177. void
  178. prtstat(sfsp, maxwidth)
  179.     register struct statfs *sfsp;
  180.     long maxwidth;
  181. {
  182.     long used, availblks, inodes;
  183.     static int timesthrough;
  184.  
  185.     if (maxwidth < 11)
  186.         maxwidth = 11;
  187.     if (++timesthrough == 1) {
  188.         printf("%-*.*s%s    used   avail capacity",
  189.             maxwidth, maxwidth, "Filesystem",
  190.             kflag ? "  kbytes" : "512-blks");
  191.         if (iflag)
  192.             printf(" iused   ifree  %%iused");
  193.         printf("  Mounted on\n");
  194.     }
  195.     printf("%-*.*s", maxwidth, maxwidth, sfsp->f_mntfromname);
  196.     used = sfsp->f_blocks - sfsp->f_bfree;
  197.     availblks = sfsp->f_bavail + used;
  198.     printf("%8ld%8ld%8ld",
  199.         sfsp->f_blocks * sfsp->f_fsize / (kflag ? 1024 : 512),
  200.         used * sfsp->f_fsize / (kflag ? 1024 : 512),
  201.         sfsp->f_bavail * sfsp->f_fsize / (kflag ? 1024 : 512));
  202.     printf("%6.0f%%",
  203.         availblks == 0 ? 100.0 : (double)used / (double)availblks * 100.0);
  204.     if (iflag) {
  205.         inodes = sfsp->f_files;
  206.         used = inodes - sfsp->f_ffree;
  207.         printf("%8ld%8ld%6.0f%% ", used, sfsp->f_ffree,
  208.            inodes == 0 ? 100.0 : (double)used / (double)inodes * 100.0);
  209.     } else 
  210.         printf("  ");
  211.     printf("  %s\n", sfsp->f_mntonname);
  212. }
  213.  
  214. /*
  215.  * This code constitutes the old df code for extracting
  216.  * information from filesystem superblocks.
  217.  */
  218. #include <ufs/fs.h>
  219. #include <errno.h>
  220. #include <fstab.h>
  221.  
  222. union {
  223.     struct fs iu_fs;
  224.     char dummy[SBSIZE];
  225. } sb;
  226. #define sblock sb.iu_fs
  227.  
  228. int    fi;
  229. int    bread();
  230.  
  231. void
  232. ufs_df(file, maxwidth)
  233.     char *file;
  234.     long maxwidth;
  235. {
  236.     extern int errno;
  237.     struct statfs statfsbuf;
  238.     register struct statfs *sfsp;
  239.     char *mntpt;
  240.     static int synced;
  241.  
  242.     if (synced++ == 0)
  243.         sync();
  244.  
  245.     if ((fi = open(file, O_RDONLY)) < 0) {
  246.         fprintf(stderr, "df: %s: %s\n", file, strerror(errno));
  247.         return;
  248.     }
  249.     if (bread((long)SBOFF, (char *)&sblock, SBSIZE) == 0) {
  250.         (void) close(fi);
  251.         return;
  252.     }
  253.     sfsp = &statfsbuf;
  254.     sfsp->f_type = MOUNT_UFS;
  255.     sfsp->f_flags = 0;
  256.     sfsp->f_fsize = sblock.fs_fsize;
  257.     sfsp->f_bsize = sblock.fs_bsize;
  258.     sfsp->f_blocks = sblock.fs_dsize;
  259.     sfsp->f_bfree = sblock.fs_cstotal.cs_nbfree * sblock.fs_frag +
  260.         sblock.fs_cstotal.cs_nffree;
  261.     sfsp->f_bavail = (sblock.fs_dsize * (100 - sblock.fs_minfree) / 100) -
  262.         (sblock.fs_dsize - sfsp->f_bfree);
  263.     if (sfsp->f_bavail < 0)
  264.         sfsp->f_bavail = 0;
  265.     sfsp->f_files =  sblock.fs_ncg * sblock.fs_ipg;
  266.     sfsp->f_ffree = sblock.fs_cstotal.cs_nifree;
  267.     sfsp->f_fsid.val[0] = 0;
  268.     sfsp->f_fsid.val[1] = 0;
  269.     if ((mntpt = getmntpt(file)) == 0)
  270.         mntpt = "";
  271.     bcopy((caddr_t)mntpt, (caddr_t)&sfsp->f_mntonname[0], MNAMELEN);
  272.     bcopy((caddr_t)file, (caddr_t)&sfsp->f_mntfromname[0], MNAMELEN);
  273.     prtstat(sfsp, maxwidth);
  274.     (void) close(fi);
  275. }
  276.  
  277. long lseek();
  278.  
  279. int
  280. bread(off, buf, cnt)
  281.     long off;
  282.     char *buf;
  283.     int cnt;
  284. {
  285.     int n;
  286.     extern errno;
  287.  
  288.     (void) lseek(fi, off, SEEK_SET);
  289.     if ((n=read(fi, buf, cnt)) != cnt) {
  290.         /* probably a dismounted disk if errno == EIO */
  291.         if (errno != EIO) {
  292.             printf("\nread error off = %ld\n", off);
  293.             printf("count = %d; errno = %d\n", n, errno);
  294.         }
  295.         return (0);
  296.     }
  297.     return (1);
  298. }
  299.