/* df.c - report free disk space.
 *
 * Copyright 2006 Rob Landley <rob@landley.net>
 *
 * See http://opengroup.org/onlinepubs/9699919799/utilities/df.html

USE_DF(NEWTOY(df, "Pkt*a", TOYFLAG_USR|TOYFLAG_SBIN))

config DF
  bool "df"
  default y
  help
    usage: df [-t type] [FILESYSTEM ...]

    The "disk free" command shows total/used/available disk space for
    each filesystem listed on the command line, or all currently mounted
    filesystems.

    -t type	Display only filesystems of this type.

config DF_PEDANTIC
  bool "options -P and -k"
  default y
  depends on DF
  help
    usage: df [-Pk]

    -P	The SUSv3 "Pedantic" option
    -k	Sets units back to 1024 bytes (the default without -P)

    Pedantic provides a slightly less useful output format dictated by Posix,
    and sets the units to 512 bytes instead of the default 1024 bytes.
*/

#define FOR_df
#include "toys.h"

GLOBALS(
  struct arg_list *fstype;

  long units;
)

static void show_mt(struct mtab_list *mt)
{
  int len;
  long long size, used, avail, percent, block;
  char *device;

  // Return if it wasn't found (should never happen, but with /etc/mtab...)
  if (!mt) return;

  // If we have -t, skip other filesystem types
  if (TT.fstype) {
    struct arg_list *al;

    for (al = TT.fstype; al; al = al->next) 
      if (!strcmp(mt->type, al->arg)) break;

    if (!al) return;
  }

  // If we don't have -a, skip synthetic filesystems
  if (!(toys.optflags & FLAG_a) && !mt->statvfs.f_blocks) return;

  // Figure out how much total/used/free space this filesystem has,
  // forcing 64-bit math because filesystems are big now.
  block = mt->statvfs.f_bsize ? mt->statvfs.f_bsize : 1;
  size = (block * mt->statvfs.f_blocks) / TT.units;
  used = (block * (mt->statvfs.f_blocks-mt->statvfs.f_bfree)) / TT.units;
  avail = (block * (getuid() ? mt->statvfs.f_bavail : mt->statvfs.f_bfree))
      / TT.units;
  if (!(used+avail)) percent = 0;
  else {
    percent = (used*100)/(used+avail);
    if (used*100 != percent*(used+avail)) percent++;
  }

  device = *mt->device == '/' ? realpath(mt->device, NULL) : NULL;
  if (!device) device = mt->device;

  // Figure out appropriate spacing
  len = 25 - strlen(device);
  if (len < 1) len = 1;
  if (CFG_DF_PEDANTIC && (toys.optflags & FLAG_P)) {
    xprintf("%s %lld %lld %lld %lld%% %s\n", device, size, used, avail,
      percent, mt->dir);
  } else {
    xprintf("%s% *lld % 10lld % 9lld % 3lld%% %s\n", device, len,
      size, used, avail, percent, mt->dir);
  }

  if (device != mt->device) free(device);
}

void df_main(void)
{
  struct mtab_list *mt, *mtstart, *mtend;

  // Handle -P and -k
  TT.units = 1024;
  if (CFG_DF_PEDANTIC && (toys.optflags & FLAG_P)) {
    // Units are 512 bytes if you select "pedantic" without "kilobytes".
    if ((toys.optflags&(FLAG_P|FLAG_k)) == FLAG_P) TT.units = 512;
    printf("Filesystem %ld-blocks Used Available Capacity Mounted on\n",
      TT.units);
  } else puts("Filesystem\t1K-blocks\tUsed Available Use% Mounted on");

  if (!(mtstart = xgetmountlist(0))) return;
  mtend = dlist_terminate(mtstart);

  // If we have a list of filesystems on the command line, loop through them.
  if (*toys.optargs) {
    char **next;

    for(next = toys.optargs; *next; next++) {
      struct stat st;

      // Stat it (complain if we can't).
      if(stat(*next, &st)) {
        perror_msg("`%s'", *next);
        continue;
      }

      // Find and display this filesystem.  Use _last_ hit in case of
      // overmounts (which is first hit in the reversed list).
      for (mt = mtend; mt; mt = mt->prev) {
        if (st.st_dev == mt->stat.st_dev) {
          show_mt(mt);
          break;
        }
      }
    }
  } else {
    // Loop through mount list to filter out overmounts.
    for (mt = mtend; mt; mt = mt->prev) {
      struct mtab_list *mt2, *mt3;

      // 0:0 is LANANA null device
      if (!mt->stat.st_dev) continue;

      // Filter out overmounts.
      mt3 = mt;
      for (mt2 = mt->prev; mt2; mt2 = mt2->prev) {
        if (mt->stat.st_dev == mt2->stat.st_dev) {
          // For --bind mounts, take show earliest mount
          if (!strcmp(mt->device, mt2->device)) {
            if (!toys.optflags & FLAG_a) mt3->stat.st_dev = 0;
            mt3 = mt2;
          } else mt2->stat.st_dev = 0;
        }
      }
    }
    // Cosmetic: show filesystems in creation order
    for (mt = mtstart; mt; mt = mt->next) if (mt->stat.st_dev) show_mt(mt);
  }

  if (CFG_TOYBOX_FREE) llist_traverse(mtstart, free);
}
