[comp.binaries.ibm.pc.d] du for Dos

bdc@bdcsys.hou.tx.us (Brian Carlton) (10/20/89)

Does anyone know of an implementation of the *nix program du for
Dos?  I am looking for a command-line one, preferable one that takes
into account the block size of the disk.  Thanks for any help


--  
Brian Carlton
bdc@bdcsys.hou.tx.us          carlton@rice.edu
...!uunet!sugar!bdcsys!bdc

caa@garnet.ssd.cdc.com (Charles A. Anderson) (10/24/89)

This is a little program I wrote while experimenting with the findfirst
and findnext call in the turbo-c library.  It does not exactly mimic
the unix du output, but I didn't want it to. Sample output is:

C:\PC>du
4940    4940    C:\PC\KA9Q
0       0       C:\PC\TS
862     862     C:\PC\MOD2
52      52      C:\PC\TRAVELL\SYSGEN
18      18      C:\PC\TRAVELL\SYSPRINT
20      90      C:\PC\TRAVELL
478     478     C:\PC\ANARKEY
6936    13306   C:\PC
32636  Total KBytes, 5842   KBytes Available, 2048 Bytes per Cluster

First column is space used in the directory, second column is summed space
for a directory and it's subdirectories.  All default numbers are in Kbytes.
Files are rounded up in size to the cluster size when summed. (i.e. a 2 byte
file on a disk with 2048 bytes per cluster is counted as 2048 bytes.)
Known bugs, it doesn't find hidden files (since findfirst and findnext didn't
give them back to me even though I had the flags set to tell me everything.)
and doesn't figure out the size of the directories.

-------------------------------cut here---------------------------------
/*
 *     Turbo C du v1.4
 *
 *     By Charles Anderson
 *	Copyright 1987 by Charles Anderson, All rights reserved.
 *	You may use and freely distribute this program, but you
 *	may not sell it, or claim you wrote it.  If you modify it
 *	to make it more usefull, I would appreciate a copy of the
 *	modifications.  This software is distributed as is, with
 *	no warranties implied whatsoever.  You may not remove this
 *	notice.  Please give credit where credit is due.
 *
 *     revisions:
 *     v1.0    08/14/87   Evolved from hacking with TSweep.          -CAA-
 *     v1.1    --/--/--   Never Existed.
 *     v1.2    09/07/87   Reversed the order it scanned directories. -CAA-
 *     v1.3    10/02/87   Fixed unix style totaling, and nextdir.
 *                        Changed from clusters to kbytes.           -CAA-
 *     v1.4    10/05/87   added -?utsc options.                      -CAA-
 *
 *     Known bugs:  Doesn't find hidden directories or files.
 *                  Space taken by directory clusters is not counted.
 *                  If you break it in the middle, your in a different
 *                     directory. (most of the time.)
 */

#include <conio.h>
#include <dir.h>
#include <dos.h>
#include <string.h>
#include <ctype.h>
#include <process.h>

int   bpc;
float kpc;

#define nclus(size, bpc)  ((((size)%(bpc))==0)?(size)/(bpc):((size)/(bpc))+1)

#define TRUE  1
#define FALSE 0
#define BOOL  int

BOOL UNIXLIKE = TRUE;
BOOL SPACE    = TRUE;
BOOL TOTAL    = FALSE;
BOOL CLUSTER  = FALSE;


/****************************************************************************/

unsigned clusterusage (void)
{

  struct ffblk fb;
         int   clus;

  if (findfirst("*.*", &fb, FA_RDONLY | FA_HIDDEN | FA_SYSTEM | FA_ARCH))
    return 0;
  clus = nclus (fb.ff_fsize, bpc);
  while (!findnext (&fb))
    clus += nclus (fb.ff_fsize, bpc);
  return clus;
}

/****************************************************************************/

BOOL nextdir (       BOOL  *first,
              struct ffblk *fb,
                     char  *dir)
{

  if (*first) {
    *first = FALSE;
    findfirst ("*.*", fb, FA_DIREC | FA_HIDDEN);
    if (strcmp (fb->ff_name, ".") && strcmp (fb->ff_name, "..") &&
        fb->ff_attrib == FA_DIREC) {
      strcpy (dir, fb->ff_name);
      return TRUE;
    }
  }
  while (!findnext (fb))
    if (strcmp (fb->ff_name, ".") && strcmp (fb->ff_name, "..") &&
        fb->ff_attrib == FA_DIREC) {
      strcpy (dir, fb->ff_name);
      return TRUE;
    }
  return FALSE;
}

/****************************************************************************/

float dirs (char *path)
{
  struct ffblk    fb;
         char     dir      [14];
         char     newpath  [255];
         unsigned clus;
         float    tot      = 0;
                  BOOL     firstdir = TRUE;

  chdir(path);
  while (nextdir (&firstdir, &fb, dir)) {
    strcpy (newpath, path);
    if (newpath[strlen (newpath)-1] != '\\')
      strcat (newpath, "\\");
    strcat (newpath, dir);
    tot += dirs (newpath);
    chdir (path);
  }
  clus = clusterusage ();
  if (CLUSTER)
    tot +=clus;
  else
    tot += clus * kpc;
  if (UNIXLIKE && SPACE)
    cprintf ("%-6.0f  %-6.0f  %s\r\n", (CLUSTER) ? clus : (clus * kpc), tot,
      path);
  else
    if (UNIXLIKE)
      cprintf ("%-6.0f  %s\r\n", tot, path);
    else
      if (SPACE)
    cprintf ("%-6.0f  %s\r\n", (CLUSTER) ? clus : (clus * kpc), path);
  return tot;
}

/****************************************************************************/

void main(int argc, char *argv[])
{

  struct dfree df;
  static char  path     [256];
  static char  origpath [256];
         int   i = 1;
         int   j = 1;

  getcwd (origpath, 255);
  while (argc > i) {
    if (*argv[i] == '-') {
      switch (toupper(argv[i][j])) {
        case 'U':
          UNIXLIKE = TRUE;
          SPACE = !SPACE;
          break;

        case 'T':
          TOTAL = TRUE;
          break;

        case 'C':
          CLUSTER = TRUE;
          break;

        case 'S':
          SPACE = TRUE;
          UNIXLIKE = !UNIXLIKE;
          break;

        case '?':
          cputs ("PC-DU Usage:\r\n\tDU [-utcks?] [path]\r\n");
          cputs ("Options:\r\n\t-u Unix like output\r\n");
          cputs ("\t-t Total Disk usage only\r\n");
          cputs ("\t-c Output in clusters instead ok KBytes\r\n");
          cputs ("\t-k Output in KBytes. (Default)\r\n");
          cputs ("\t-s Output space used in subdirectory\r\n");
          cputs ("Default output prints both space used in the subdirectory");
          cputs (" and unix like totals.\r\n");
          cputs ("And disk totals\r\n");
          exit (0);
          break;

        default:
          cputs ("Unknown Option: ");
          cputs (argv[i]);
          cputs ("\r\n");
          argv[i][j--] = '?';
          break;
      }
      if (!argv[i][++j])
        i++;
    } else {
      if (chdir (argv[i])) {
        cputs ("Could not change to specified directory.  Abort\r\n");
        exit (-1);
      }
      i++;
    }
  }
  getdfree (0, &df);
  bpc = df.df_bsec * df.df_sclus;
  kpc = bpc / 1024.0;
  getcwd (path, 255);
  if (!TOTAL)
    dirs (path);
  if (!UNIXLIKE || SPACE)
    if (CLUSTER)
      cprintf("%-6u Total Clusters, %-6u Clusters Available, %-4u "
              "Bytes per Cluster\r\n", df.df_total, df.df_avail, bpc);
    else
      cprintf("%-6.0f Total KBytes, %-6.0f KBytes Available, %-4u "
              "Bytes per Cluster\r\n", df.df_total * kpc,
              df.df_avail * kpc, bpc);
  chdir (origpath);
 }
-------------------------------cut here---------------------------------
-- 
Charles Anderson |  caa@garnet.ssd.cdc.com \ Disclaimer: I said what?
----------------/     caa@midgard.mn.org     \           But CDC didn't.
If someone deserves a cheap shot, by all means, give it to them.

s854106@minyos.xx.rmit.oz (Brett Murphy) (10/25/89)

bdc@bdcsys.hou.tx.us (Brian Carlton) writes:

>Does anyone know of an implementation of the *nix program du for
>Dos?  I am looking for a command-line one, preferable one that takes
>into account the block size of the disk.  Thanks for any help


>--  
>Brian Carlton
>bdc@bdcsys.hou.tx.us          carlton@rice.edu
>...!uunet!sugar!bdcsys!bd

I own a version of DU but it never seems to work correctly (ie wrong sizes)
I assume this has something to do with the block sizes you mention.
It is public domain, mail me if you are interested.
c

jwbirdsa@phoenix.Princeton.EDU (James Webster Birdsall) (10/30/89)

bdc@bdcsys.hou.tx.us (Brian Carlton) writes:
>Does anyone know of an implementation of the *nix program du for
>Dos?  I am looking for a command-line one, preferable one that takes
>into account the block size of the disk.  Thanks for any help

   I wrote a DU program for DOS. Not quite the same as the *NIX
(different options), and I didn't take into account the block size.
If you want it, email me.


[NOTE TO ANYBODY WHO MIGHT HAVE DU by James W. Birdsall, versions 1.x:
 Please destroy all copies of it. It's a real dog and it was just sheer
 coincidence that it happened to work on my system when I wrote it. 
 Since then, I've entirely rewritten it (lost the original source to a
 disk crash, so it's ALL new) and it actually works. Anybody who wants
 a copy, email me...  
 Thanks.
]

-- 
James W. Birdsall  jwbirdsa@phoenix.Princeton.EDU  jwbirdsa@pucc.BITNET
   ...allegra!princeton!phoenix!jwbirdsa   Compu$erve: 71261,1731
"For it is the doom of men that they forget." -- Merlin