URI: 
       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 }