#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include <errno.h> #include <unistd.h> #include <mntent.h> #include <sys/statvfs.h> #include "human.h" #include "config.h" char a_flag; char h_flag; char *t_flag; off_t block = 1024; int print(const struct mntent *me) { struct statvfs disk; if (!strcmp(me->mnt_fsname, "none")) return 0; if (statvfs(me->mnt_dir, &disk) < 0) return 1; if (!a_flag) if (!strcmp(me->mnt_fsname, "/dev/root") || disk.f_blocks == 0) return 0; if (t_flag && strcmp(t_flag, me->mnt_type)) return 0; off_t bs = disk.f_frsize / block; off_t total = disk.f_blocks * bs; off_t avail = disk.f_bfree * bs; off_t used = total - avail; off_t capacity = (used * 100 + 1) / (avail + used + 1); if (h_flag) { char total_s[MU_HUMAN_BUF_SIZE + 1]; char used_s[MU_HUMAN_BUF_SIZE + 1]; char avail_s[MU_HUMAN_BUF_SIZE + 1]; snprintf(total_s, sizeof(total_s), "%s", mu_humansize(total * block, block)); snprintf(used_s, sizeof(used_s), "%s", mu_humansize(used * block, block)); snprintf(avail_s, sizeof(avail_s), "%s", mu_humansize(avail * block, block)); printf("%-20s %12s %10s %9s %9s %3jd%% %s\n", me->mnt_fsname, me->mnt_type, total_s, used_s, avail_s, capacity, me->mnt_dir); } else printf("%-20s %12s %12jd %12jd %12jd %12jd%% %s\n", me->mnt_fsname, me->mnt_type, total, used, avail, capacity, me->mnt_dir); return 0; } int main(int argc, char **argv) { int opt; while ((opt = getopt(argc, argv, "hHat:")) != -1) { switch (opt) { case 'h': h_flag = 1; break; case 'H': h_flag = 1; block = 1000; break; case 'a': a_flag = 1; break; case 't': t_flag = optarg; break; default: puts("df [hHat]\n\t-h Human readable (1024)\n\t-a Show all\n\t-H Human readable (1000)\n\t-t TYPE Print only mounts of this type"); return 0; } } argv += optind; argc -= optind; FILE *fp = setmntent("/proc/mounts", "r"); if (fp == NULL) { fprintf(stderr, "df: %s\n", strerror(errno)); return 1; } if (h_flag) puts("Filesystem Type Size Used Available Use% Mounted on"); else puts("Filesystem Type Size Used Available Use% Mounted on"); int ret = 0; struct mntent *me; while ((me = getmntent(fp)) != NULL) { if (argc) { for (int i = 0; i < argc; i++) { if (!strcmp(argv[i], me->mnt_fsname) || !strcmp(argv[i], me->mnt_dir)) if (print(me)) ret = 1; } } else print(me); } endmntent(fp); return ret; }