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 }