[comp.sys.amiga] amiga du command

joemu@nscpdc.NSC.COM (Joe Mueller) (12/19/86)

This is a short program that I whipped up to determine the disk usage of a
file or directory. This compiles under lattice C with a simple
cc -o du du.c

The only known bug is that the number of blocks for a file does not include
the dos overhead for the file. If someone knows how to figure that in, let
me know and I'll incorporate the change.

#!/bin/sh-----cut here-----cut here-----cut here-----cut here-----
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	du.c
#	du.doc
echo shar: extracting du.c
cat - << \SHAR_EOF > du.c
/*
 * du.c
 * (C) 1986 Software Solution, all rights reserved
 */

/*
 * du is patterned after the Unix(tm) du command. Its default action is to
 * give the total number of disk blocks used by a directory and recursively,
 * its subdirectories. If the -a flag is used the command reports the number
 * of blocks used for both files and directories. The -s flag gives the
 * sum of all blocks used by a directory and its subdirectories. The -a and
 * -s flags are mutually exclusive. If a name is not given, the current
 * directory is used.
 *
 * The command tells you if a file is a directory if the -a flag is used
 * to lessen the chance of confusion.
 *
 * Bug reports or suggestions should be sent to:
 *    The Software Solution
 *    16850 S.W. Timberland Dr.
 *    Aloha, Oregon 97007
 */

#include <stdio.h>
#include "libraries/dos.h"
#include "libraries/dosextens.h"
#include "exec/memory.h"

extern struct FileLock *Lock(), *CurrentDir();

struct FileLock *src_dir_lock;  /* Lock on source dir */

int s_flag = 0;   /* summary only flag */
int a_flag = 0;   /* list disk usage for both files and directories */

char *myname;     /* name by which this command has been called i.e."du" */

main(argc, argv)
   int argc;
   char **argv;
{
   int j;
   char *cur_dir;  /* current directory name */
   int total;

   myname = *argv;

   /* parse the arguments */
   argv++;
   while ((*argv)[0] == '-') {   /* handle options */
      j = 1;               /* start past the "-" character */
      while ((*argv)[j]) {
         switch ((*argv)[j++]) {
            case 's':
            case 'S':
               if (a_flag)
                  goto usage;
               s_flag++;   /* sum only */
               break;
            case 'a':
            case 'A':
               if (s_flag)
                  goto usage;
               a_flag++;   /* all files reported */
               break;
            default:
               goto usage;
         }
      }
      argv++;
   }

   if (*argv) {
      while (cur_dir = *argv++) {
         total = sum(cur_dir);
         if (total)
             printf("%s %d\n",cur_dir, total);
      }
   } else {
      total = sum(argv);
      printf(". %d\n", total);
   }

   exit (0);

usage:
   fprintf(stderr,"%s: usage %s [-a] [-s] name ...\n", myname, myname);
   exit (1);
}

int
sum(fn)
char *fn;  /* directory file name */
{
   register int total, val;
   register struct FileLock *fl;
   register struct FileInfoBlock *fib;
   struct FileLock *ol;    /* old current directory lock */

   fib = (struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock),MEMF_CLEAR);
   if (fib == NULL) {
      fprintf(stderr,"%s: unable to allocate space for fileinfo block\n",myname);
      return 0;
   }
   fl = Lock(fn, ACCESS_READ);
   if (fl == 0) {
      fprintf(stderr,"%s: unable to lock %s\n", myname, fn);
      FreeMem(fib, sizeof(struct FileInfoBlock));
      return 0;
   }
   total = 0;
   ol = NULL;
   if (Examine(fl,fib)) {  /* take a look at the directory */
      if (fib->fib_DirEntryType > 0) {   /* it's a directory */
         ol = CurrentDir(fl);
      }
      total += fib->fib_NumBlocks;
      while (ExNext(fl, fib)) { /* found a file or directory */
         if (fib->fib_DirEntryType > 0) { /* found a subdirectory */
               val = sum(fib->fib_FileName);
               if (!s_flag)
                  printf("%s (dir) %d\n", fib->fib_FileName, val);
         } else {
            val = fib->fib_NumBlocks;
            if (a_flag)
               printf("%s %d\n", fib->fib_FileName, val);
         }
         total += val;
      }
      FreeMem(fib, sizeof(struct FileInfoBlock));
      if (ol != NULL)
         CurrentDir(ol);   /* change directories back */
      UnLock(fl);
      return total;
   }
}
SHAR_EOF
echo shar: extracting du.doc
cat - << \SHAR_EOF > du.doc

Format:        DU [-A][-S][<name>*]

Template:      DU "-A/S,-S/S,"names"

Purpose:       To tell you how many disk blocks are used by files


Specification:

DU tells the user how many disk blocks are used by files or directories.
DU without any arguments will give the total number of disk blocks used
by files within the current directory and any subdirectories below it. If
the -A switch is used, the command will list each file with the number of
blocks used by it next to its name. Directories will be signified by (dir)
following the name and the total number of blocks used by files and
directories within it will follow that. The -S switch will give the sum
only for the directory names given it. The command is typically used to
determine if sufficient room exists on a disk for a file or subdirectory
to be copied to it. The -A and -S switches are mutually exclusive.

Examples:

DU df1:

gives total number of blocks used by files and subdirectories of df1:
without listing each file name (lists directories only).

DU -S df1:

gives the total number of blocks used by files and subdirectories of df1:
without listing each subdirectory name.

DU -A df1:c

gives the number of blocks used by each file and subdirectory within df1:c
while listing each file.

See also:
         INFO,COPY
SHAR_EOF