morpheus-base

morpheus base system
git clone git://git.2f30.org/morpheus-base.git
Log | Files | Refs

df.c (2915B)


      1 /* See LICENSE file for copyright and license details. */
      2 #include <sys/statvfs.h>
      3 
      4 #include <mntent.h>
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <string.h>
      8 
      9 #include "util.h"
     10 
     11 static long blksize = 512;
     12 static int aflag = 0;
     13 static int hflag = 0;
     14 static int kflag = 0;
     15 
     16 static void mnt_show(const char *fsname, const char *dir);
     17 
     18 static void
     19 usage(void)
     20 {
     21 	eprintf("usage: %s [-a]\n", argv0);
     22 }
     23 
     24 int
     25 main(int argc, char *argv[])
     26 {
     27 	struct mntent *me = NULL;
     28 	FILE *fp;
     29 
     30 	ARGBEGIN {
     31 	case 'a':
     32 		aflag = 1;
     33 		break;
     34 	case 'h':
     35 		hflag = 1;
     36 		kflag = 0;
     37 		break;
     38 	case 'k':
     39 		kflag = 1;
     40 		hflag = 0;
     41 		blksize = 1024;
     42 		break;
     43 	case 's':
     44 	case 'i':
     45 		eprintf("not implemented\n");
     46 	default:
     47 		usage();
     48 	} ARGEND;
     49 
     50 	if (hflag)
     51 		printf("Filesystem         Size       Used      "
     52 		       "Avail Capacity   Mounted on\n");
     53 	else
     54 		printf("Filesystem  %ld-blocks      Used     "
     55 		       "Avail Capacity  Mounted on\n", blksize);
     56 
     57 	fp = setmntent("/proc/mounts", "r");
     58 	if (!fp)
     59 		eprintf("setmntent %s:", "/proc/mounts");
     60 	while ((me = getmntent(fp)) != NULL) {
     61 		if (aflag == 0)
     62 			if (strcmp(me->mnt_type, "rootfs") == 0)
     63 				continue;
     64 		mnt_show(me->mnt_fsname, me->mnt_dir);
     65 	}
     66 	endmntent(fp);
     67 
     68 	return 0;
     69 }
     70 
     71 #define CALC_POWER(n, power, base, i) do { \
     72 	while (n > power) {                \
     73 		power = power * base;      \
     74 		i++;                       \
     75 	}                                  \
     76 } while(0)
     77 
     78 static void
     79 print_human(
     80 	const char         *fsname,
     81 	unsigned long long total,
     82 	unsigned long long used,
     83 	unsigned long long avail,
     84 	int                capacity,
     85 	const char         *dir)
     86 {
     87 	long base = 1024;
     88 	unsigned long long power_total = base;
     89 	unsigned long long power_used = base;
     90 	unsigned long long power_avail = base;
     91 	char postfixes[] = {'B', 'K', 'M', 'G', 'T', 'P', 'E'};
     92 	int i = 0, j = 0, k = 0;
     93 
     94 	total = total * blksize;
     95 	used = used * blksize;
     96 	avail = avail * blksize;
     97 
     98 	CALC_POWER(total, power_total, base, i);
     99 	CALC_POWER(used, power_used, base, j);
    100 	CALC_POWER(avail, power_avail, base, k);
    101 
    102 	total = i ? total / (power_total / base) : total;
    103 	used = j ? used / (power_used / base) : used;
    104 	avail = k ? avail / (power_avail / base) : avail;
    105 	printf("%-12s %9llu%c %9llu%c %9llu%c %7d%%  %s\n",
    106 	       fsname, total, postfixes[i], used, postfixes[j],
    107 	       avail, postfixes[k], capacity, dir);
    108 }
    109 
    110 static void
    111 mnt_show(const char *fsname, const char *dir)
    112 {
    113 	struct statvfs s;
    114 	unsigned long long total, used, avail;
    115 	int capacity = 0;
    116 	int bs;
    117 
    118 	statvfs(dir, &s);
    119 
    120 	bs = s.f_frsize / blksize;
    121 	total = s.f_blocks * bs;
    122 	avail = s.f_bfree * bs;
    123 	used = total - avail;
    124 
    125 	if (used + avail) {
    126 		capacity = (used * 100) / (used + avail);
    127 		if (used * 100 != capacity * (used + avail))
    128 			capacity++;
    129 	}
    130 
    131 	if (hflag)
    132 		print_human(fsname, total, used, avail, capacity, dir);
    133 	else
    134 		printf("%-12s %9llu %9llu %9llu %7d%%  %s\n",
    135 		       fsname, total, used, avail, capacity, dir);
    136 }