kent@sparky.IMD.Sterling.COM (Kent Landfield) (01/03/91)
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@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@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@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@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@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@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@uunet.uu.net.