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