chris@lxn.eds.com (Christopher D. Orr) (07/19/89)
jmm@ecijmm.UUCP (John Macdonald) writes: >In article <1018@cniysc.cinnet.COM> yun@cinnet.COM (Yun-seng Chao) writes: >| >|Uh, wasn't there something called "bdf" posted last year that was able to >|parse the Sys V "df" command? Why not use some of that code for usg >|systems to do some of this parsing (with acknowledgements to the original >|author, of course)? >"bdf" was a perl program that converted Sys V df output into a format >similar to Berkely df. I kind of doubt that Henry and Geoff would want >to include perl as a pre-requisite for C news. >-- >John Macdonald The version of "bdf" that I have is written in 'C'. The code is very short so I'll include it with this article for those of you who might want it. --Chris -------------------------------- CUT HERE ---------------------------------- /* bdf - berkeley DF for system-V systems * vix 16jan88 [written - from scratch] * * This code is public-domain, but please leave this notice intact and give me * appropriate credit if you write a man page for it. If you send me bug fixes * and enhancements, I will release new versions from time to time. * Paul Vixie, paul%vixie@uunet.uu.net * * This is not nearly good enough for the obfuscated C contest. Next time? * * Known to work on INTERACTIVE 386/ix, and should therefore work perfectly * on Microport/386 and whatever the AT&T 6386 calls its OS. Should work okay * on 3B's. Should work, in fact, anywhere where the output of 'df -t' is * the same as 'System V/386', which may or may not be all SysV.[23] systems. */ #include <stdio.h> #include <string.h> #define TRUE 1 #define FALSE 0 static char *PROGNAME = "bdf"; static void usage() { fprintf(stderr, "usage: %s [-i]\n", PROGNAME); exit(4); } main(argc, argv) int argc; char *argv[]; { void bdf(); int iflag = FALSE; int optind = argc; char command_buf[300], *ptr = command_buf; if (!(PROGNAME = strrchr(argv[0], '/'))) PROGNAME = argv[0]; if (argc > 1) if (argv[1][0] == '-') if (argv[1][1] == 'i') { iflag = TRUE; optind = 2; } else usage(); else optind = 1; ptr += sprintf(ptr, "/bin/df -t"); for (; optind < argc; optind++) ptr += sprintf(ptr, " %s", argv[optind]); bdf(iflag, command_buf); } static void bdf(iflag, df_command) int iflag; char *df_command; { void output_part1(), output_part2(), output_part3(); void header_part1(), header_part2(), header_part3(); char filesys[50], device[50]; int fblocks, finodes, tblocks, tinodes; FILE *df; if (!(df = popen(df_command, "r"))) { fprintf(stderr, "error executing <%s> command\n", df_command); perror("popen"); exit(2); } header_part1(); if (iflag) header_part2(); header_part3(); while (EOF != fscanf(df, " %[^(] (%[^)]%*s %d blocks %d i-nodes", filesys, device, &fblocks, &finodes)) { if (EOF == fscanf(df, " total: %d blocks %d i-nodes", &tblocks, &tinodes)) { /* perror("fscanf#2"); */ exit(0); } output_part1(device, fblocks/2, tblocks/2); if (iflag) output_part2(finodes, tinodes); output_part3(filesys); } } /************* Filesystem kbytes used avail capacity iused ifree %iused Mounted on /dev/dsk/0s1 xxxxxxx xxxxxxx xxxxxxx xxx% xxxxxx xxxxxx xxx% /foo/bar *************/ static void header_part1() { printf(" Filesystem kbytes used avail capacity"); } static void header_part2() { printf(" iused ifree %%iused"); } static void header_part3() { printf(" Mounted on\n"); } static void output_part1(device, free_kb, total_kb) char *device; int free_kb, total_kb; { int used_kb, capacity; used_kb = total_kb - free_kb; if (total_kb != 0) capacity = (100 * used_kb) / total_kb; else capacity = 0; printf("%12s %7d %7d %7d %3d%% ", device, total_kb, used_kb, free_kb, capacity); } static void output_part2(free_inodes, total_inodes) int free_inodes, total_inodes; { int used_inodes = total_inodes - free_inodes; int percent_used = (100 * used_inodes) / total_inodes; printf("%6d %6d %3d%% ", used_inodes, free_inodes, percent_used); } static void output_part3(filesys) char *filesys; { printf(" %s\n", filesys); } -- Christopher D. Orr | US MAIL: Electronic Data Systems (EDS) UUCP: vu-vlsi!lxn!chris | Lanark Building or chris%lxn.uucp@rutgers.edu | Center Valley, PA 18034 or lehi3b15!lxn!chris | Voice: (215) 282-1213
allbery@nc386.UUCP (Brandon S. Allbery) (07/24/89)
There is a very simple way to extract the number of free blocks from a
System V "df"; it's currently working on nc386 (SCO Xenix), telotech (Altos
System V) and ncoast (AT&T System III(!)), each of which has a slightly
different "df" output (in fact, I had to rewrite "bdf"-for-Perl to work on
ncoast).
Extracted from our "spacefor":
## this is set up for the stupid System V df
# which only proves that Collyer and Spencer don't understand System V df....
df $arg | sed 's/^[^ ]* *([^)][^)]*): *\([0-9][0-9]*\) .*$/\1/' | awk "{
nb = (\$1 - $desire) * $dfunit / $1
if (nb > 10000)
nb = 10000 # ensure representable as integer
nb = int(nb)
if (nb <= 0)
print 0
else
print nb
exit
}"
Note the "sed" command in the pipeline; it extracts the "blocks" part of the
"df" output, and does so quite portably.
I left the "awk" mostly as is, but could have written the sed script as part
of the awk script instead or performed other optimizations.
++Brandon
--
Brandon S. Allbery, moderator of comp.sources.misc allbery@NCoast.ORG
uunet!hal.cwru.edu!ncoast!allbery ncoast!allbery@hal.cwru.edu
* This message brought to you courtesy the "Watcher" for the 4th NCoast *