v16i001: dosdu - DOS version of the du command, Part01/01

Kent Landfield kent at sparky.IMD.Sterling.COM
Thu Jan 3 17:43:48 AEST 1991


Submitted-by: uunet!stimage.mqcc.mq.oz.au!mallsop (Mark Allsop)
Posting-number: Volume 16, Issue 1
Archive-name: dosdu/part01

Hi,
  Here's a unix-like du program for MSDOS.  I hope people find it helpful.
Cheers,
-Mark.

 Mark Allsop                                              Computer Scientist 
 email: mallsop at suna.mqcc.mq.oz.au                The Statistical Laboratory 
 Phone: At MacUni: (61 2) 805-8592  / \      Macquarie University, Australia 
 Fax  :          : (61 2) 805-7433   |   This one goes up to 11.....

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then feed it
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix at uunet.uu.net if you want that tool.
# If this archive is complete, you will see the following message at the end:
#		"End of shell archive."
# Contents:  du.c
# Wrapped by kent at sparky on Thu Jan  3 00:42:17 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'du.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'du.c'\"
else
echo shar: Extracting \"'du.c'\" \(7543 characters\)
sed "s/^X//" >'du.c' <<'END_OF_FILE'
X Fax  :          : (61 2) 805-7433   |   This one goes up to 11.....
X
X/*
X *	du.c: Calculate disk usage similar to UNIX version
X *
X * Compiles under TC.  May need mods for MSC.
X *
X * PLEASE : If you make any improvements, send a copy to me so I can make
X *               changes available to everyone.....
X *
X *  Author: Mark Allsop (Internet address: mallsop at suna.mqcc.mq.oz.au)
X *
X *  See #define VERSION and __DATE__ in compile for current version and date
X *
X *  This software is placed into the public domain.  The author grants the right
X * to anyone to alter this program, provided that any upgrades or modifications
X * are mailed back to him.
X *  This program may not be sold for any profit.  The source code may, however ,
X * be used as part of any other package PROVIDED appropriate credit is given in
X * the program source code AND documentation and that no fee is ever charged
X * for just the code in this program.  This entire comment block MUST appear
X * in the code at the place of usage of the code in this module.
X *  For further information, contact the author!
X *  This disclaimer is intended to stop people ripping off my software, and
X * using what was free and making money from it.  I call such people *scum*.
X * I encourage you to release other utilities into the public domain so that
X * life can be made easier for all of us.
X */
X
X/*
X * This currently changes the directories to find files.  This is slow, but I
X * havn't had the time to do it properly yet.  You should just use strings
X * and the path and cat/uncat them.
X */
X
X/*
X * Options:-
X *	-a: generate an entry for every file
X *	-s: only display grand total for each of the file names
X *	-r: display error info about unreadable directories, etc.
X *      -k: display sizes in Kb
X *      -m: display sizes in Mb
X */
X
X#include <conio.h>
X#include <stdio.h>
X#include <string.h>
X#include <dos.h>
X#include <dir.h>
X
X#define VERSION	"1.0"
X#define MAXPATHLEN 100
X#define conv_size(size)	((size_type == KB) ? (size) / 1024 : (size_type==MB) \
X					      ? (size) / 1048576 : (size))
X
Xint c_break(void);
Xvoid sw_flags (int *ac, char **av, char *letters, int *flags);
Xunsigned long find_usage(char *path, int quiet);
Xvoid du_help(char *fname);
X
Xenum Size_type {BYTES, KB, MB} size_type;
X
Xint all, disp_errs;
Xint curr_disk, diff_drv;
Xchar cwd_org[MAXPATHLEN], cwd_org2[MAXPATHLEN];
X
Xmain(int ac, char **av)
X{
X	/* all & disp_errs are global to save stack space during recusrion */
X  int i, j, flags[5], quiet;
X  char dir[MAXPATHLEN];
X
X  if (av[1][0] == '?') {
X    du_help(av[0]);
X    return(0);
X  }
X
X  ctrlbrk(c_break);	/* Catch ctrl-c's so you don't get left elsewhere */
X
X  sw_flags(&ac, av, "arskm", flags);
X  all = flags[0];
X  disp_errs = flags[1];
X  quiet = flags[2];
X  size_type = (flags[4]) ? MB : ((flags[3]) ? KB : BYTES);
X
X  printf("Sizes given are in %s\n", (size_type == KB) ? "Kb"
X				 : (size_type == MB) ? "Mb" : "bytes");
X  getcwd(cwd_org, MAXPATHLEN);	/* Save cwd so we can return to it */
X  curr_disk = getdisk();
X  if (ac == 1) {
X    strcpy(dir, ".");
X    printf("%12ld %s\n", conv_size(find_usage(dir, quiet)), dir);
X  } else {
X    for (i=1; i<ac; i++) {
X    strcpy(dir, av[i]);
X    if (dir[1] == ':' && strlen(dir) >= 2) {
X      setdisk(toupper(dir[0])-'A');
X      getcwd(cwd_org2, MAXPATHLEN);	/* Save cwd so we can return to it */
X      diff_drv=1;	/* Diff drive - need to restore 2wice *
X
X      j=2;
X      while(dir[j] != '\0'){
X	dir[j-2] = dir[j];
X	j++;
X      }
X      dir[j-2] = dir[j];
X      if (dir[0] == '\0')	/* No name! Can't have that now, can we! */
X        strcpy(dir, ".");
X    }
X    else
X      diff_drv=0;		/* Same drive as before */
X    if (chdir(dir) == 0)	/* Directory exists */
X      printf("%12ld %s\n", conv_size(find_usage(dir, quiet)), dir);
X    else
X      printf("%s: No such file or directory\n", dir);
X    setdisk(curr_disk);
X    chdir(cwd_org);		/* Return to original directory */
X    }
X    if (diff_drv) {
X      chdir(cwd_org2);		/* Reset for each command */
X      diff_drv=0;
X    }
X  }
X  if (diff_drv)
X    chdir(cwd_org2);		/* Reset for each command */
X  setdisk(curr_disk);
X  chdir(cwd_org);		/* Return to original directory */
X  return(0);
X}
X
Xunsigned long find_usage(char *path, int quiet)
X{
X  char dpath[MAXPATHLEN];
X  struct ffblk fblk;
X  unsigned long size = 0, tsiz;
X
X  if (findfirst("*.*", &fblk, 0xff) == 0) {
X    do {
X      if (!strcmp(fblk.ff_name, ".") || !strcmp(fblk.ff_name, ".."))
X	continue;
X      switch (fblk.ff_attrib) {
X	case FA_DIREC:
X	  size += (unsigned long)fblk.ff_fsize;
X	  if (chdir(fblk.ff_name) == 0) {
X	    sprintf(dpath, "%s\\%s", path, fblk.ff_name);
X	    tsiz = find_usage(dpath, quiet);
X	    if (!quiet)
X	      printf("%12ld %s\n", conv_size(tsiz), dpath);
X	    size += tsiz;
X	    chdir("..");
X          }
X          else if (disp_errs)
X            printf("%s\\%s: Permission Denied\n", path, fblk.ff_name);
X	  break;
X	case FA_LABEL:
X	case FA_RDONLY:
X	case FA_HIDDEN:
X	case FA_SYSTEM:
X	case FA_ARCH:
X	default:
X	  size += (unsigned long)fblk.ff_fsize;
X          if (all)
X	    printf("%12ld %s\\%s\n", conv_size(fblk.ff_fsize), path,
X							    fblk.ff_name);
X	  break;
X      }
X    } while (findnext(&fblk) == 0);
X  }
X  return(size);			/* Default: can't have had any size! */
X}
X
Xvoid du_help(char *fname)
X{
X  printf("%s [-s][-a][-r][-k][-m] [list of names]: disk usage\n", fname);
X  printf("     -s: Only display grand total for each specified name\n");
X  printf("     -a: Generate an entry for each file\n");
X  printf("     -r: Display errors for directories that can't be opened\n");
X  printf("     -k: Display sizes in Kb\n");
X  printf("     -m: Display sizes in Mb\n");
X  printf("list of names: list of file/directory names for usage of.\n");
X  printf(
X"    Author: Mark Allsop, Internet address: mallsop at suna.mqcc.mq.oz.au.\n");
X  printf("    Date: %s.  Version: %s.  Public domain program.\n",
X							  __DATE__, VERSION);
X}
X
Xint c_break(void)
X{
X  printf("User interrupt!\n");
X  if (diff_drv)
X    chdir(cwd_org2);		/* Reset for each command */
X  chdir(cwd_org);		/* Return to original directory */
X  setdisk(curr_disk);
X  exit(1);			/* They want out! */
X}
X
X
X/*
X * swflag.c: Parse flag type switches.
X *
X * sw_flag (&ac, av, "letters", flags)
X *
X * For each letter, if it is found in a switch which contains
X * only valid letters from the sequence "letters" then the corresponding
X * flag is set true, else set false. The flags count the number of occurrences
X
X * of the switch letter. Thus, the program can use repetition for
X * emphasis.
X * e.g. letter "v" for verbosity; -vv would mean extra verbose.
X *
X * HISTORY
X * 19-Sep-86  Leonard Hamey (lgh) at Carnegie-Mellon University
X *	Fixed bug which allowed a lone hyphen to be matched as a flags
X *	argument with no flags.
X *
X *  9-Aug-86  Leonard Hamey (lgh) at Carnegie-Mellon University
X *	Created.
X */
X
Xvoid sw_flags(ac, av, letters, flags)
Xint *ac;
Xregister char **av;
Xregister char *letters;
Xregister int *flags;
X{
X  register char *p;
X  register int i, j;
X  if (letters[0] == '-')
X    letters++;
X  for (i = 0; letters[i] != '\0'; i++)
X    flags[i] = 0;
X  for (i = *ac; --i >= 1; )
X  {
X    p = av[i];
X    if (*p == '-' && p[1] != '\0')
X    {
X      for (p++; *p != '\0'; p++)
X	if (strchr (letters, *p) == 0)
X	  break;
X      if (*p != '\0')
X	continue;
X      for (p = av[i]+1; *p != '\0'; p++)
X      { /*
X	 * Count occurrences of the flag
X	 */
X	flags[strchr(letters,*p) - letters]++;
X      }
X      /*
X       * Discard argument.
X       */
X      (*ac)--;
X      for (j = i; j < *ac; j++)
X	av[j] = av[j+1];
X      av[j] = NULL;
X    }
X  }
X}
X
END_OF_FILE
if test 7543 -ne `wc -c <'du.c'`; then
    echo shar: \"'du.c'\" unpacked with wrong size!
fi
# end of 'du.c'
fi
echo shar: End of shell archive.
exit 0
exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent at sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent at uunet.uu.net.



More information about the Comp.sources.misc mailing list