/* 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, "HPkht*a[-HPkh]", TOYFLAG_SBIN))

config DF
  bool "df"
  default y
  help
    usage: df [-HPkh] [-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.

    -P	The SUSv3 "Pedantic" option
    -k	Sets units back to 1024 bytes (the default without -P)
    -h	Human readable output (K=1024)
    -H	Human readable output (k=1000)
    -t type	Display only filesystems of this type.

    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;
  int column_widths[5];
  int header_shown;
)

static void measure_column(int col, const char *s)
{
  size_t len = strlen(s);

  if (TT.column_widths[col] < len) TT.column_widths[col] = len;
}

static void measure_numeric_column(int col, long long n)
{
  snprintf(toybuf, sizeof(toybuf), "%lld", n);
  return measure_column(col, toybuf);
}

static void show_header()
{
  TT.header_shown = 1;

  // The filesystem column is always at least this wide.
  if (TT.column_widths[0] < 14) TT.column_widths[0] = 14;

  if (toys.optflags & (FLAG_H|FLAG_h)) {
    xprintf("%-*s Size  Used Avail Use%% Mounted on\n",
            TT.column_widths[0], "Filesystem");
  } else {
    const char *blocks_label = TT.units == 512 ? "512-blocks" : "1K-blocks";
    const char *use_label = toys.optflags & FLAG_P ? "Capacity" : "Use%";

    measure_column(1, blocks_label);
    measure_column(2, "Used");
    measure_column(3, "Available");
    measure_column(4, use_label);
    xprintf("%-*s %*s %*s %*s %*s Mounted on\n",
            TT.column_widths[0], "Filesystem",
            TT.column_widths[1], blocks_label,
            TT.column_widths[2], "Used",
            TT.column_widths[3], "Available",
            TT.column_widths[4], use_label);

    // For the "Use%" column, the trailing % should be inside the column.
    TT.column_widths[4]--;
  }
}

static void show_mt(struct mtab_list *mt, int measuring)
{
  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;

  if (measuring) {
    measure_column(0, device);
    measure_numeric_column(1, size);
    measure_numeric_column(2, used);
    measure_numeric_column(3, avail);
  } else {
    if (!TT.header_shown) show_header();

    if (toys.optflags & (FLAG_H|FLAG_h)) {
      char *size_str = toybuf, *used_str = toybuf+64, *avail_str = toybuf+128;
      int hr_flags = (toys.optflags & FLAG_H) ? HR_1000 : 0;

      human_readable(size_str, size, hr_flags);
      human_readable(used_str, used, hr_flags);
      human_readable(avail_str, avail, hr_flags);
      xprintf("%-*s %4s  %4s  %4s % 3lld%% %s\n",
        TT.column_widths[0], device,
        size_str, used_str, avail_str, percent, mt->dir);
    } else xprintf("%-*s %*lld %*lld %*lld %*lld%% %s\n",
        TT.column_widths[0], device,
        TT.column_widths[1], size,
        TT.column_widths[2], used,
        TT.column_widths[3], avail,
        TT.column_widths[4], percent,
        mt->dir);
  }

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

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

  if (toys.optflags & (FLAG_H|FLAG_h)) {
    TT.units = 1;
  } else {
    // Units are 512 bytes if you select "pedantic" without "kilobytes".
    TT.units = toys.optflags & FLAG_P ? 512 : 1024;
  }

  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) {
    // Measure the names then output the table.
    for (measuring = 1; measuring >= 0; --measuring) {
      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
              || (st.st_rdev && (st.st_rdev == mt->stat.st_dev)))
          {
            show_mt(mt, measuring);
            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, 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;
        }
      }
    }

    // Measure the names then output the table.
    for (measuring = 1; measuring >= 0; --measuring) {
      // Cosmetic: show filesystems in creation order.
      for (mt = mtstart; mt; mt = mt->next) {
        if (mt->stat.st_dev) show_mt(mt, measuring);
      }
    }
  }

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