An acquaintance worked with HP-UX, AIX and SunOS machines and was complaining that the df/bdf command worked differently everywhere. So I wrote the di program.
The di program was started in 1994. As of 2025, that is 31 years of programming and maintenance. The original release notice was posted on 1994-02-27 to the alt.sources Usenet group.
In the beginning I used SCCS as the source code control system, then RCS, and now Mercurial. My standard desktop system was at first System V.4, then Solaris (2.4-8), then Linux (Debian, Linux Mint, MX Linux (IIRC)).
At first, the makefile used the methods of the time. There was a target for each platform and the code had #if statements based on which system was being coded for.
I received quite a few contributions for various systems and integrated those into di.
For version 2.0 in 1999, I switched to using perl's metadist configuration tool, and the code was re-written to use capability based testing.
Version 3.0 in 2001 switched to iffe (ksh's configuration tool) as the configuration tool, and version 4.0 in 2005 dropped support for perl's metadist. iffe's license required the AT&T logo to be displayed, so very soon afterwards, I created a perl script to do the configuration. iffe was removed in version 4.17.
For Version 4.18, I created a shell script to do the configuration in addition to the perl script.
In version 4.20, the configuration scripts were moved to their own package, mkconfig.
The mkconfig package was enhanced and improved over time to be compatible with a variety of Bourne shell compliant shells: ash, dash, bash 2, 3, 4, 5, ksh 88, 93, mksh, pdksh, AIX sh, HP-UX sh, Solaris sh, Tru64 sh, modern yash, and osh (oil-shell).
One interesting find in writing mkconfig was that bash was one of the slowest shells. Removing the useless use of quotation marks speeds up bash quite a bit. Opening the various files using the static file descriptors is much, much faster, though this makes the shell scripts much harder to read and maintain. Other speed-ups are testing for +=, internal expr handling, and typeset.
The other thing to note with the various shells is that though their quoting and backslash handling is internally consistent, it is not consistent with other shells. Single quotes mixed with backslashes can be interpolated very differently and echo and printf may handle them differently. I was lucky, and didn't run into this issue for quite a while. For portability, just stay away from backslashes within single quotes.
There are various other quirks and crashes in the various shells that had to be worked around.
There are also a lot of myths and misinformation about shell scripting and portability issues to be found on the internet.
mkconfig allowed me to make di very portable and execute on some very old systems.
In order to test di on various machines (in order to ensure portability), I created many virtual machines with older Linux, FreeBSD, NetBSD, and Solaris. I also used polarhome as their service had many very old operating systems.
Version 4.35 introduced support for checking quotas. It seemed to me that if an account was limited by quotas, the disk space reported should be the quota limits, not the actual disk space.
Quotas are a bit of a pain to work with, since every type of filesystem may have its own quota interface. The exception is Dragonfly BSD, which added a virtual quota interface (nice!).
Version 4.52 dropped support for K&R compilers. Function prototypes are now required.
di has been ported to the following systems in the past. Version 5.x drops support for Syllable and VMS.
A/UX, AIX, BeOS, BSD, BSDI, Convex, Cray UNICOS, Cray UNICOS/mk, DragonFly BSD, FreeBSD, Haiku, HP/UX, Linux, MacOS, MirOS, NetBSD, Next, OpenBSD, OS/2, OSF/1, Pyramid, SCO OpenServer, SCO Unix, Sequent Dynix and PT/x, SGI Irix, Solaris, SunOS, Syllable, System V.3, System V.4, Tru64, ULTRIX, UnixWare, VMS, Windows, Xenix
di has used either doubles or long doubles to hold the disk space values (as a long double has a mantissa of approximately 34 digits).
In 2025, I decided that in order to support the very large disk sizes that modern systems have, and to future-proof di, di should use one of the multi precision libraries. Version 5/6 supports either the use of MPDecimal, GMP or libtommath for multi precision support. If none of these are available, the value is stored in the largest supported type: long double, double, uint64_t, long long, or long.
Multi precision support will ensure that di works with very large disks in the future, and will also ensure that the numeric calculations are accurate.
Use of the multi precision libraries is optional, as long doubles are quite capable (as of 2025).
At the same time, there has been something I've been wanting to do with di for a long time. Create a proper library and API. The main di program now uses the new shared library and API to create the output.
I also created a cmake build and install process for modern systems. This will work better in the future than the mkconfig configuration tool.
The README lists many contributors from the early days. In addition, polarhome and SPI deserve many thanks for making various systems available for cross-platform testing.