117049c45SAxel Dörfler // df - for Haiku
217049c45SAxel Dörfler //
317049c45SAxel Dörfler // authors, in order of contribution:
417049c45SAxel Dörfler // jonas.sundstrom@kirilla.com
517049c45SAxel Dörfler // axeld@pinc-software.de
617049c45SAxel Dörfler //
717049c45SAxel Dörfler
817049c45SAxel Dörfler
917049c45SAxel Dörfler #include <Volume.h>
1017049c45SAxel Dörfler #include <Directory.h>
1117049c45SAxel Dörfler #include <Path.h>
1217049c45SAxel Dörfler
1317049c45SAxel Dörfler #include <fs_info.h>
1417049c45SAxel Dörfler
1517049c45SAxel Dörfler #include <stdio.h>
16758b1d0eSIngo Weinhold #include <stdlib.h>
1717049c45SAxel Dörfler #include <string.h>
1817049c45SAxel Dörfler #include <ctype.h>
1917049c45SAxel Dörfler #include <errno.h>
2017049c45SAxel Dörfler
2117049c45SAxel Dörfler
2217049c45SAxel Dörfler void
PrintFlag(uint32 deviceFlags,uint32 testFlag,char yes,char no)23*75d92dbdSAdrien Destugues PrintFlag(uint32 deviceFlags, uint32 testFlag, char yes, char no)
2417049c45SAxel Dörfler {
25*75d92dbdSAdrien Destugues printf("%c", deviceFlags & testFlag ? yes : no);
2617049c45SAxel Dörfler }
2717049c45SAxel Dörfler
2817049c45SAxel Dörfler
2917049c45SAxel Dörfler void
PrintMountPoint(dev_t device,bool verbose)3017049c45SAxel Dörfler PrintMountPoint(dev_t device, bool verbose)
3117049c45SAxel Dörfler {
3217049c45SAxel Dörfler char mount[B_PATH_NAME_LENGTH];
3317049c45SAxel Dörfler mount[0] = '\0';
3417049c45SAxel Dörfler
3517049c45SAxel Dörfler BVolume volume(device);
3617049c45SAxel Dörfler BDirectory root;
3717049c45SAxel Dörfler if (volume.GetRootDirectory(&root) == B_OK) {
3817049c45SAxel Dörfler BPath path(&root, NULL);
3917049c45SAxel Dörfler if (path.InitCheck() == B_OK)
4017049c45SAxel Dörfler strlcpy(mount, path.Path(), sizeof(mount));
4117049c45SAxel Dörfler else
4217049c45SAxel Dörfler strlcpy(mount, "?", sizeof(mount));
4317049c45SAxel Dörfler }
4417049c45SAxel Dörfler
4517049c45SAxel Dörfler if (verbose)
4617049c45SAxel Dörfler printf(" Mounted at: %s\n", mount);
4717049c45SAxel Dörfler else {
48b03efd58SDariusz Knociński printf("%-17s ", mount);
49b03efd58SDariusz Knociński if (strlen(mount) > 17)
50b03efd58SDariusz Knociński printf("\n%17s ", "");
5117049c45SAxel Dörfler }
5217049c45SAxel Dörfler }
5317049c45SAxel Dörfler
5417049c45SAxel Dörfler
5517049c45SAxel Dörfler void
PrintType(const char * fileSystem)5617049c45SAxel Dörfler PrintType(const char *fileSystem)
5717049c45SAxel Dörfler {
58b03efd58SDariusz Knociński char type[16];
5917049c45SAxel Dörfler strlcpy(type, fileSystem, sizeof(type));
6017049c45SAxel Dörfler
61b03efd58SDariusz Knociński printf("%-9s", type);
6217049c45SAxel Dörfler }
6317049c45SAxel Dörfler
6417049c45SAxel Dörfler
6517049c45SAxel Dörfler const char *
ByteString(int64 numBlocks,int64 blockSize)6617049c45SAxel Dörfler ByteString(int64 numBlocks, int64 blockSize)
6717049c45SAxel Dörfler {
6817049c45SAxel Dörfler double blocks = 1. * numBlocks * blockSize;
6917049c45SAxel Dörfler static char string[64];
7017049c45SAxel Dörfler
7117049c45SAxel Dörfler if (blocks < 1024)
72deb9fbcbSAlexander von Gluck IV sprintf(string, "%" B_PRId64, numBlocks * blockSize);
7317049c45SAxel Dörfler else {
74b03efd58SDariusz Knociński const char *units[] = {"KiB", "MiB", "GiB", "TiB", "PiB", "EiB",
75b03efd58SDariusz Knociński "ZiB", "YiB", NULL};
7617049c45SAxel Dörfler int32 i = -1;
7717049c45SAxel Dörfler
7817049c45SAxel Dörfler do {
7917049c45SAxel Dörfler blocks /= 1024.0;
8017049c45SAxel Dörfler i++;
8117049c45SAxel Dörfler } while (blocks >= 1024 && units[i + 1]);
8217049c45SAxel Dörfler
8317049c45SAxel Dörfler sprintf(string, "%.1f %s", blocks, units[i]);
8417049c45SAxel Dörfler }
8517049c45SAxel Dörfler
8617049c45SAxel Dörfler return string;
8717049c45SAxel Dörfler }
8817049c45SAxel Dörfler
8917049c45SAxel Dörfler
9017049c45SAxel Dörfler void
PrintBlocks(int64 blocks,int64 blockSize,bool showBlocks)9117049c45SAxel Dörfler PrintBlocks(int64 blocks, int64 blockSize, bool showBlocks)
9217049c45SAxel Dörfler {
9317049c45SAxel Dörfler char temp[1024];
9417049c45SAxel Dörfler
9517049c45SAxel Dörfler if (showBlocks)
96deb9fbcbSAlexander von Gluck IV sprintf(temp, "%" B_PRId64, blocks * (blockSize / 1024));
9717049c45SAxel Dörfler else
9817049c45SAxel Dörfler strcpy(temp, ByteString(blocks, blockSize));
9917049c45SAxel Dörfler
10017049c45SAxel Dörfler printf("%10s", temp);
10117049c45SAxel Dörfler }
10217049c45SAxel Dörfler
10317049c45SAxel Dörfler
10417049c45SAxel Dörfler void
PrintVerbose(dev_t device)10517049c45SAxel Dörfler PrintVerbose(dev_t device)
10617049c45SAxel Dörfler {
10717049c45SAxel Dörfler fs_info info;
10817049c45SAxel Dörfler if (fs_stat_dev(device, &info) != B_OK) {
10917049c45SAxel Dörfler fprintf(stderr, "Could not stat fs: %s\n", strerror(errno));
11017049c45SAxel Dörfler return;
11117049c45SAxel Dörfler }
11217049c45SAxel Dörfler
113deb9fbcbSAlexander von Gluck IV printf(" Device No.: %" B_PRIdDEV "\n", info.dev);
11417049c45SAxel Dörfler PrintMountPoint(info.dev, true);
11517049c45SAxel Dörfler printf(" Volume Name: \"%s\"\n", info.volume_name);
11617049c45SAxel Dörfler printf(" File System: %s\n", info.fsh_name);
11717049c45SAxel Dörfler printf(" Device: %s\n", info.device_name);
11817049c45SAxel Dörfler
11917049c45SAxel Dörfler printf(" Flags: ");
120*75d92dbdSAdrien Destugues PrintFlag(info.flags, B_FS_HAS_QUERY, 'Q', '-');
121*75d92dbdSAdrien Destugues PrintFlag(info.flags, B_FS_HAS_ATTR, 'A', '-');
122*75d92dbdSAdrien Destugues PrintFlag(info.flags, B_FS_HAS_MIME, 'M', '-');
123*75d92dbdSAdrien Destugues PrintFlag(info.flags, B_FS_IS_SHARED, 'S', '-');
124*75d92dbdSAdrien Destugues PrintFlag(info.flags, B_FS_IS_PERSISTENT, 'P', '-');
125*75d92dbdSAdrien Destugues PrintFlag(info.flags, B_FS_IS_REMOVABLE, 'R', '-');
126*75d92dbdSAdrien Destugues PrintFlag(info.flags, B_FS_IS_READONLY, '-', 'W');
12717049c45SAxel Dörfler
128deb9fbcbSAlexander von Gluck IV printf("\n I/O Size: %10s (%" B_PRIdOFF " byte)\n",
129deb9fbcbSAlexander von Gluck IV ByteString(info.io_size, 1), info.io_size);
130deb9fbcbSAlexander von Gluck IV printf(" Block Size: %10s (%" B_PRIdOFF " byte)\n",
131deb9fbcbSAlexander von Gluck IV ByteString(info.block_size, 1), info.block_size);
132deb9fbcbSAlexander von Gluck IV printf(" Total Blocks: %10s (%" B_PRIdOFF " blocks)\n",
133deb9fbcbSAlexander von Gluck IV ByteString(info.total_blocks, info.block_size), info.total_blocks);
134deb9fbcbSAlexander von Gluck IV printf(" Free Blocks: %10s (%" B_PRIdOFF " blocks)\n",
135deb9fbcbSAlexander von Gluck IV ByteString(info.free_blocks, info.block_size), info.free_blocks);
136deb9fbcbSAlexander von Gluck IV printf(" Total Nodes: %" B_PRIdOFF "\n", info.total_nodes);
137deb9fbcbSAlexander von Gluck IV printf(" Free Nodes: %" B_PRIdOFF "\n", info.free_nodes);
138deb9fbcbSAlexander von Gluck IV printf(" Root Inode: %" B_PRIdINO "\n", info.root);
13917049c45SAxel Dörfler }
14017049c45SAxel Dörfler
14117049c45SAxel Dörfler
14217049c45SAxel Dörfler void
PrintCompact(dev_t device,bool showBlocks,bool all)14317049c45SAxel Dörfler PrintCompact(dev_t device, bool showBlocks, bool all)
14417049c45SAxel Dörfler {
14517049c45SAxel Dörfler fs_info info;
14617049c45SAxel Dörfler if (fs_stat_dev(device, &info) != B_OK)
14717049c45SAxel Dörfler return;
14817049c45SAxel Dörfler
14917049c45SAxel Dörfler if (!all && (info.flags & B_FS_IS_PERSISTENT) == 0)
15017049c45SAxel Dörfler return;
15117049c45SAxel Dörfler
15217049c45SAxel Dörfler PrintType(info.fsh_name);
15317049c45SAxel Dörfler PrintBlocks(info.total_blocks, info.block_size, showBlocks);
15417049c45SAxel Dörfler PrintBlocks(info.free_blocks, info.block_size, showBlocks);
15517049c45SAxel Dörfler
15617049c45SAxel Dörfler printf(" ");
157*75d92dbdSAdrien Destugues PrintFlag(info.flags, B_FS_HAS_QUERY, 'Q', '-');
158*75d92dbdSAdrien Destugues PrintFlag(info.flags, B_FS_HAS_ATTR, 'A', '-');
159*75d92dbdSAdrien Destugues PrintFlag(info.flags, B_FS_HAS_MIME, 'M', '-');
160*75d92dbdSAdrien Destugues PrintFlag(info.flags, B_FS_IS_SHARED, 'S', '-');
161*75d92dbdSAdrien Destugues PrintFlag(info.flags, B_FS_IS_PERSISTENT, 'P', '-');
162*75d92dbdSAdrien Destugues PrintFlag(info.flags, B_FS_IS_REMOVABLE, 'R', '-');
163*75d92dbdSAdrien Destugues PrintFlag(info.flags, B_FS_IS_READONLY, '-', 'W');
16417049c45SAxel Dörfler
165*75d92dbdSAdrien Destugues printf(" %24s ", info.device_name);
166*75d92dbdSAdrien Destugues PrintMountPoint(info.dev, false);
167*75d92dbdSAdrien Destugues printf("\n");
16817049c45SAxel Dörfler }
16917049c45SAxel Dörfler
17017049c45SAxel Dörfler
17117049c45SAxel Dörfler void
ShowUsage(const char * programName)17217049c45SAxel Dörfler ShowUsage(const char *programName)
17317049c45SAxel Dörfler {
17417049c45SAxel Dörfler printf("usage: %s [--help | --blocks, -b | -all, -a] [<path-to-device>]\n"
17517049c45SAxel Dörfler " -a, --all\tinclude all file systems, also those not visible from Tracker\n"
17617049c45SAxel Dörfler " -b, --blocks\tshow device size in blocks of 1024 bytes\n"
17717049c45SAxel Dörfler "If <path-to-device> is used, detailed info for that device only will be listed.\n"
17817049c45SAxel Dörfler "Flags:\n"
17917049c45SAxel Dörfler " Q: has query\n"
18017049c45SAxel Dörfler " A: has attribute\n"
18117049c45SAxel Dörfler " M: has mime\n"
18217049c45SAxel Dörfler " S: is shared\n"
18317049c45SAxel Dörfler " P: is persistent (visible in Tracker)\n"
18417049c45SAxel Dörfler " R: is removable\n"
18517049c45SAxel Dörfler " W: is writable\n", programName);
18617049c45SAxel Dörfler exit(0);
18717049c45SAxel Dörfler }
18817049c45SAxel Dörfler
18917049c45SAxel Dörfler
19017049c45SAxel Dörfler int
main(int argc,char ** argv)191f89856e5SMichael Lotz main(int argc, char **argv)
19217049c45SAxel Dörfler {
19317049c45SAxel Dörfler char *programName = argv[0];
19417049c45SAxel Dörfler if (strrchr(programName, '/'))
19517049c45SAxel Dörfler programName = strrchr(programName, '/') + 1;
19617049c45SAxel Dörfler
19717049c45SAxel Dörfler bool showBlocks = false;
19817049c45SAxel Dörfler bool all = false;
19917049c45SAxel Dörfler dev_t device = -1;
20017049c45SAxel Dörfler
20117049c45SAxel Dörfler while (*++argv) {
20217049c45SAxel Dörfler char *arg = *argv;
20317049c45SAxel Dörfler if (*arg == '-') {
20417049c45SAxel Dörfler while (*++arg && isalpha(*arg)) {
20517049c45SAxel Dörfler switch (arg[0]) {
20617049c45SAxel Dörfler case 'a':
20717049c45SAxel Dörfler all = true;
20817049c45SAxel Dörfler break;
20917049c45SAxel Dörfler case 'b':
21017049c45SAxel Dörfler showBlocks = true;
21117049c45SAxel Dörfler break;
212045af160SFrançois Revol case 'h':
213045af160SFrançois Revol // human readable units in Unix df
214045af160SFrançois Revol break;
21517049c45SAxel Dörfler default:
21617049c45SAxel Dörfler ShowUsage(programName);
21717049c45SAxel Dörfler }
21817049c45SAxel Dörfler }
21917049c45SAxel Dörfler if (arg[0] == '-') {
22017049c45SAxel Dörfler arg++;
22117049c45SAxel Dörfler if (!strcmp(arg, "all"))
22217049c45SAxel Dörfler all = true;
22317049c45SAxel Dörfler else if (!strcmp(arg, "blocks"))
22417049c45SAxel Dörfler showBlocks = true;
22517049c45SAxel Dörfler else
22617049c45SAxel Dörfler ShowUsage(programName);
22717049c45SAxel Dörfler }
22817049c45SAxel Dörfler } else
22917049c45SAxel Dörfler break;
23017049c45SAxel Dörfler }
23117049c45SAxel Dörfler
23217049c45SAxel Dörfler // Do we already have a device? Then let's print out detailed info about that
23317049c45SAxel Dörfler
23417049c45SAxel Dörfler if (argv[0] != NULL) {
23517049c45SAxel Dörfler PrintVerbose(dev_for_path(argv[0]));
23617049c45SAxel Dörfler return 0;
23717049c45SAxel Dörfler }
23817049c45SAxel Dörfler
23917049c45SAxel Dörfler // If not, then just iterate over all devices and give a compact summary
24017049c45SAxel Dörfler
241*75d92dbdSAdrien Destugues printf(" Type Total Free Flags Device Mounted on\n"
242b03efd58SDariusz Knociński "--------- --------- --------- ------- ------------------------ -----------------\n");
24317049c45SAxel Dörfler
24417049c45SAxel Dörfler int32 cookie = 0;
24517049c45SAxel Dörfler while ((device = next_dev(&cookie)) >= B_OK) {
24617049c45SAxel Dörfler PrintCompact(device, showBlocks, all);
24717049c45SAxel Dörfler }
24817049c45SAxel Dörfler
24917049c45SAxel Dörfler return 0;
25017049c45SAxel Dörfler }
251